1 作用域(Scope)
1.1 作用域的定义
作用域
指的是变量可被访问的有效范围。
1.2 作用域的分类
对于 js 来说,作用域有下面三类:
全局作用域
变量在全局范围有效。
局部作用域(又叫函数作用域)
变量在声明它的函数体中,及在这个函数体嵌套的任意函数体内有效。
块作用域(es6 新增的语法)
变量在语句块内有效。
2 变量对象 ( Variable Object )
**变量对象
,顾名思义就是保存变量的对象,只要是保存变量的对象,都可以称为变量对象
。winows 对象、活动对象、闭包等都是保存变量的对象,都属于变量对象
**。
3 活动对象(Activation Object)
活动对象是在函数执行时产生的变量对象,活动对象保存了函数的局部变量、window对象。
4 作用域链 [[scopes]]
作用域链
是函数的一个内部属性 [[scopes]],是由函数可访问的所有外部作用域对象
组成的数组。[[scopes]] 属性不能通过程序读取,只能由 js 引擎读取。js 通过**作用域链
**实现了静态作用域(指作用域由定义时而非运行时决定)。
**作用域链
**将可以将不同函数关联起来,并保证了函数解析变量的顺序。
1 | function A(aArg){ |
上面代码 chrome 输出截图:

firefox 输出截图:

firefox 并没有输出 [[scopes]] 属性,chrome 虽然输出了,但却无法访问 [[scopes]] 属性。
5 执行上下文(或叫执行环境)
执行上下文是函数执行时创建的一个内部对象,定义了函数执行时的环境。
函数每次执行时,都会创建对应的执行上下文,多次调用函数,将会创建多个执行上下文。当函数执行完毕,执行上下文将被销毁。
执行上下文是使用函数自身的作用域 [[scopes]] 属性来进行初始化的,并将活动对象(由函数的局部变量组成)追加为其第一个元素。
5 总结
1 | var B1Alias; |

通过上面的示例和调试截图来总结下,将各个概念关联起来:
每个函数被初始化时,会包含一个数组类型的属性 [[Scopes]] (即作用域链),[[Scopes]] 的内容是由此函数可以访问的外部作用域对象组成的。
每次函数执行时,都会创建对应的执行上下文,会使用函数的 [[Scopes]] 来初始化执行上下文,并将活动对象(由函数的局部变量组成)追加到执行上下文的第一个元素。
作用域是一个范围,当把这个范围关联到某个对象时,可以把这个对象叫做作用域对象,如 windows 对象、活动对象、执行上下文 都可以称为作用域对象。
保存变量的对象称为变量对象,也就是说变量对象包括了作用域对象,但并不止作用域对象。
参考: