深入理解 javascript scope chain
2017-05-05 15:24:59 0 举报
js
作者其他创作
大纲/内容
在代码执行阶段有两个声明能修改作用域链。这就是with声明和catch语句。它们添加到作用域链的最前端
二维作用域链查找
作用域链scope chain
8
栗子:
一个执行上下文 的数据(变量、函数声明和函数的形参)作为属性存储在变量对象中。同时我们也知道变量对象在每次进入上下文时创建,并填入初始值,值的更新出现在代码执行阶段。每个上下文拥有自己的变量对象:对于全局上下文,它是全局对象自身;对于函数,它是活动对象。
AO|VO
活动对象是作用域数组的第一个对象,即添加到作用域的前端
等价于
通过构造函数创建的函数的[[scope]]总是唯一的全局对象。考虑到这一点,如通过这种函数创建除全局之外的最上层的上下文闭包是不可能的。
二维链查找。(1)作用域链环节;(2)每个作用域链--深入到原型链环节。
“foo”上下文的作用域链
“bar”上下文的作用域链
1
作用域链与一个执行上下文相关,变量对象的链用于在标识符解析中变量查找。与函数的生命周期相关。作用域链正是内部上下文所有变量对象(包括父变量对象)的列表。此链用来变量查询。
Scope: [ // Scope chain // 所有变量对象的列表 // for identifiers lookup]
barContext.AO = { z: 30};
6
在“foo”创建时,“foo”的[[scope]]属性写入函数对象
内部函数“bar”创建
抽象为
创建
全局上下文的作用域链仅包含全局对象。代码eval的上下文与当前的调用上下文(calling context)拥有同样的作用域链。
7
激活阶段(调用时)
Scope = [AO].concat([[Scope]])
对“x”、“y”、“z”的标识符解析
在函数调用时进入上下文,这时候活动对象被创建,this和作用域(作用域链)被确定。
闭包
构造函数
[[Scope]]
2
“bar”激活时(进入上下文)
3
全局上下文的变量对象
globalContext.VO === Global = { x: 10 foo: };
Scope = catchObject + AO|VO + [[Scope]]
AO
4
- \"x\"-- barContext.AO // not found-- fooContext.AO // not found-- globalContext.VO // found - 10- \"y\"-- barContext.AO // not found-- fooContext.AO // found - 20- \"z\"-- barContext.AO // found - 30
Scope = + [[Scope]]
“foo”激活时(进入上下文)
作用域特征
[[scope]]是所有父变量对象的层级链,处于当前函数上下文之上,在函数创建时存于其中。[[scope]]在函数创建时被存储--静态(不变的),永远永远,直至函数销毁。即:函数可以永不调用,但[[scope]]属性已经写入,并存储在函数对象中。
foo.[[Scope]] = [ globalContext.VO];
全局和eval上下文中的作用域链
Scope = withObject|catchObject + AO|VO + [[Scope]]
5
代码执行时对作用域链的影响
var x = 10; function foo() { var y = 20; function bar() { var z = 30; alert(x + y + z); } bar();} foo(); // 60
函数的生命周期
收藏
收藏
0 条评论
下一页