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 ...
随机推荐
- 使用Spring Cloud Feign作为HTTP客户端调用远程HTTP服务
在Spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端.我们可以使用JDK原生的URLConnection.Ap ...
- 易混HTML Entities与正确用法
在页面上,表示HTML实体有多种方式,比方有"&+name;"."&#+10进制ID"."&#x+16进制ID".而 ...
- SQL in、not in、exists和not exists的区别:
来自:http://blog.sina.com.cn/s/blog_8a0c4f130100zaw2.html 先谈谈in和exists的区别: exists:存在,后面一般都是子查询,当子查询返回行 ...
- 【中间件安全】Jboss安全加固规范
1. 适用情况 适用于使用Jboss进行部署的Web网站. 适用版本:5.x版本的Jboss服务器 2. 技能要求 熟悉Jboss安装配置,能够Jboss进行部署,并能针对站点使用Jboss进行安全加 ...
- 【CF480D】Parcels DP
[CF480D]Parcels 题意:有一个栈,有n个物品,每个物品可以选或不选.如果选了第i个物品,则获得$v_i$的收益,且第i个物品必须在$in_i$时刻入栈,$out_i$时刻出栈.每个物品还 ...
- gym101808 E
提问:我是什么品种的傻逼? 哇看到积水兴高采烈啊.然后就走上了一条不归路. 为什么不归呢,因为我这个法子就是不对的,我总是在想很多很多点围成的一块区域,然后求这一块区域的面积. 然后尝试了各种扫描方法 ...
- HttpRequest获得服务端和客户端的详细信息
参考文档:http://blog.csdn.net/u012104100/article/details/43051301 http://blog.csdn.net/u011162260/articl ...
- java 三大框架 struct2部分 实现增删该查操作
1.三层架构 表现层:接收和处理请求. MVC模型:它是一个表现层模型. 业务层:处理程序业务需求. 持久层:对数据库操作的.2.MVC模型 M:Model ...
- #define 宏定义
gcc Semaphores.c -lpthread --std=c99 1. 边际效应 2. \ 宏定义中一行写不下时,不能换行,必须\+换行 #define CPE_MAIN_PRINTF(fmt ...
- hibernate--博客
地址:http://blog.csdn.net/wangpeng047/article/category/907051