Open hzzzzzzzq opened 2 years ago
在[《JavaScript 深入之执行上下文栈》]()中提到,当 JavaScript 代码执行代码时,就会创建一个执行上下文。
对于执行上下文,都有三个重要属性:
我们来介绍一下作用域链。
在查找变量的时候,会先从当前上下文的变量对象中查找,如果没找到,就会从上一级的执行上下文的变量对象中查找,直到找到全局对象为止。
而这样由多个执行上下文的变量对象构成的链表就时作用域链。
每一个函数都有自己的作用域,内部有一个 [[scope]] 属性,当函数创建时,就会保存所有父级变量对象到其中,简单来说,[[scope]] 就是所有父级变量对象的层级链。 注意:[[scope]] 并不能代表完整的作用域链。
[[scope]]
我们来看一个例子吧
function fn1() { function fn2() { function fn3() {} } }
函数创建时,我们来看看每一个函数的 [[scope]] 为:
fn1.[[scope]] = [ globalContext.VO ]; fn2.[[scope]] = [ fn1Context.AO, globalContext.VO ]; fn3.[[scope]] = [ fn2Context.AO, fn1Context.AO, globalContext.VO ]
当函数激活时,进入函数上下文,创建 VO/AO 后,就会将活动对象添加到作用域链的前端。
VO/AO
在执行上下文中,我们将作用域链命名为 Scope
Scope
Scope = [AO].concat([[Scope]]);
我们来举个例子吧,对《JavaScript 权威指南》 中的例子进行修改
var scope = 'global scope'; function checkscope() { var scope = 'local scope'; return scope; } checkscope();
来看看执行过程吧
checkscope.[[scope]] = [ globalContext.VO ]
ECStack = [checkscopeContext, globalContext];
AO
checkscopeContext = { AO: { arguments: { length: 0 }, scope: undefined }, Scope: checkscope.[[scope]] }
checkscopeContext = { AO: { arguments: { length: 0, }, scope: undefined, }, Scope: [AO, [[Scope]]], };
checkscopeContext = { AO: { arguments: { length: 0, }, scope: 'local scope', }, Scope: [AO, [[Scope]]], };
scope
ECStack = [globalContext];
JavaScript 深入之作用域链
在[《JavaScript 深入之执行上下文栈》]()中提到,当 JavaScript 代码执行代码时,就会创建一个执行上下文。
对于执行上下文,都有三个重要属性:
我们来介绍一下作用域链。
作用域链
在查找变量的时候,会先从当前上下文的变量对象中查找,如果没找到,就会从上一级的执行上下文的变量对象中查找,直到找到全局对象为止。
而这样由多个执行上下文的变量对象构成的链表就时作用域链。
函数创建
每一个函数都有自己的作用域,内部有一个
[[scope]]
属性,当函数创建时,就会保存所有父级变量对象到其中,简单来说,[[scope]]
就是所有父级变量对象的层级链。 注意:[[scope]]
并不能代表完整的作用域链。我们来看一个例子吧
函数创建时,我们来看看每一个函数的
[[scope]]
为:函数激活
当函数激活时,进入函数上下文,创建
VO/AO
后,就会将活动对象添加到作用域链的前端。在执行上下文中,我们将作用域链命名为
Scope
我们来举个例子吧,对《JavaScript 权威指南》 中的例子进行修改
来看看执行过程吧
AO
的创建。如何创建看[《JavaScript 深入之变量对象》]()。scope
,在一开始就找到了,所有直接返回该值,函数执行完毕。函数上下文弹出执行上下文栈。