JavaScript 作用域链其实很简单
概念
作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。其本质就是一个指向变量对象的指针列表。在js中,当某个函数被调用时,会创建一个执行环境(execution context)及相应的作用域链。然后使用arguments和其他命名参数的值来初始化函数的活动对象(activation object)。在作用域链中,外部函数的活动对象始终位于第二位,外部函数的外部函数的活动对象位于第三位,......直至作为作用域终点的全局执行环境。
(1) arguments和命名参数可以去看另一篇博客 JavaScript 神奇的参数。
(2) 活动对象: 在一个函数对象被调用的时候,会创建一个活动对象。该函数的命名参数和arguments参数数组会被添加为该活动对象的属性,同时该函数体内显示声明的变量和函数,也会添加为该活动对象的属性(因为JS的提前声明机制,所以并没有立即赋值,值为undefined)。
在函数执行过程中,为了读取和写入变量的值,就需要在作用域中查找变量。看下面的例子:
function compare(value1,value2) {
if (value1 < value2){
return -1;
}else if(value1 > value2){
return 1;
}else{
return 0;
}
}
var result = compare(5,10);
以上代码先定义了compare()函数,然后在全局作用域中调用了它。当调用compare()时,会创建一个包含arguments、value1、value2的活动对象。全局执行环境的变量对象(包括result和compare)在compare() 执行环境的作用域中处于第二位。下图展示了包括上述关系的compare()函数执行时的作用域链。

从上图中可以看出compare的执行环境内部有一个属性指向当前作用域链,而compare()的活动对象就保存在作用域链的最前面(第一位)也就是下标为0的位置。全局执行环境的变量对象则处于第二位,也就是下标为1的位置。
过程大致为:在创建compare()函数时,会创建一个预先包含全局变量对象的作用域链,这个作用域链被保存在内部的[[Scope]]属性中。当调用compare()函数时,会为函数创建一个执行环境,然后通过复制函数的[[Scope]]属性中的对象构建起执行环境的作用域链。此后,又有一个活动对象被创建并推入执行环境作用域链的前端。对于这个例子中compare()函数的执行环境而言,其作用域中包含两个变量对象:本地活动对象和全局变量对象。从这里就可以看出,作用域链的本质就是一个指向量的指针列表,它只引用但不实际包含变量对象。
JavaScript 作用域链其实很简单的更多相关文章
- JavaScript作用域链
之前写过一篇JavaScript 闭包究竟是什么的文章理解闭包,觉得写得很清晰,可以简单理解闭包产生原因,但看评论都在说了解了作用域链和活动对象才能真正理解闭包,起初不以为然,后来在跟公司同事交流的时 ...
- JavaScript作用域链详解
JavaScript的作用域链还是很有味道的,搞懂了这个知识点,闭包的问题也就迎刃而解咯 1.JavaScript的全局变量和局部变量 首先,先来看看js的全局变量和局部变量,js不是块级作用域,所以 ...
- JavaScript作用域链的理解
前言 作用域是JavaScript一个很重要的概念,想要学好JavaScript就需要理解javascript作用域和作用域链的工作原理.这篇文章对JavaScript作用域链和作用域链做一个简单的介 ...
- JavaScript 作用域链图具体解释
<script type="text/javascript"> /** * 作用域链: */ var a = "a"; function hao94 ...
- 深入javascript作用域链到闭包
我之前用过闭包,用过this,虽然很多时候知道是这么一回事,但是确实理解上还不够深入.再一次看javascript高级程序设计这本书时,发现一起很多疑难问题竟然都懂了,所以总结一下一些理解,难免有错, ...
- javascript 作用域链及性能优化
在JavaScript中,函数也是对象,实际上,JavaScript里一切都是对象.函数对象和其它对象一样,拥有可以通过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性.其中一个内部属 ...
- 个人理解的javascript作用域链与闭包
闭包引入的前提个人理解是为从外部读取局部变量,正常情况下,这是办不到的.简单的闭包举例如下: function f1(){ n=100; function f2(){ alert(n); } retu ...
- javascript作用域链学习笔记
作用域链 "JavaScript中的函数运行在它们被定义的作用域里,而不是它们被执行的作用域里." --权威指南 在JavaScript中,一切皆对象,包括函数.函数对象和其它对象 ...
- (好文推荐)一篇文章看懂JavaScript作用域链
闭包和作用域链是JavaScript中比较重要的概念,首先,看看几段简单的代码. 代码1: var name = "stephenchan"; var age = 23; func ...
随机推荐
- vs2017离线安装且安装包不占用C盘空间
[参考]vs2017离线安装且安装包不占用C盘空间 第一步:下载离线安装包 https://www.visualstudio.com/zh-hans/downloads/ 在官方地址下载vs_prof ...
- puppet(4)-类、模版语言、模块
puppet(4)-类.模版语言.模块 代码重用: class, module 类 类的简单说明 类是用于公共目的的一组资源,是命名的代码块,创建后可在puppet全局进行调用,类可以继承类是我们构建 ...
- Android的TextView设置padding无效
I finally found the problem I have to set the background first before setting the padding. Setting t ...
- JAVA ftp连接池功能实现
抽象类: package com.echo.store; import java.util.Enumeration; import java.util.Hashtable; abstract clas ...
- Microsoft office 2019 正式版镜像下载
http://www.xitongtiandi.net/soft_yy/4373.htmlMicrosoft office 2019 正式版镜像下载 http://www.xitongtiandi.n ...
- centos 7 rpm方式安装mysql
一.下载rpm 二.安装 1.用rz上传到centos上,目录为/home/upload 2.解压 tar -xvf mysql-5.7.25-1.el7.x86_64.rpm-bundle.tar ...
- Oracle同义词(synonym)
oracle的同义词总结 从字面上理解就是别名的意思,和视图的功能类似.就是一种映射关系. 同义词拥有如下好处: 节省大量的数据库空间,对不同用户的操作同一张表没有多少差别; 扩展的数 ...
- H - Expedition 优先队列 贪心
来源poj2431 A group of cows grabbed a truck and ventured on an expedition deep into the jungle. Being ...
- 2.node.js (二)服务器登录注册 与 包的发布
get: 不安全 小 2k 数据会在地址栏上显示 从服务器获取 快 post: 相对安全 https 大 1G 不会 向服务器发送 慢 get:直接解析url地址 借助 url模块 var urlOb ...
- 【Swing程序设计/常用面板】
面板也是一个Swing容器,可以作为容器容纳其他组件,但是它必须要被添加到其他容器中.Swing常见的面板是JPanel面板和JScrollPanel面板. JPanel面板可以聚集一些组件来布局. ...