We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
这篇文章来讨论一下执行上下文中的另一个属性,作用域链。作用域链的本质是一个指向变量对象的指针列表。
函数的生命周期可以分为两个部分:函数创建和函数激活(即函数调用)。
函数创建 前面的文章我们知道,每个执行上下文都会有对应的变量对象。全局环境的变量对象一直存在,直到程序关闭。而函数中的局部的变量对象则是在函数执行的时候才会创建,函数执行结束后销毁。
在函数创建的时候,会预先创建一个包含上一级执行上下文变量对象的作用域,该作用域会保存在内部属性[[Scope]]中。这也意味着函数外部的作用域是在函数创建的时候就已经确定下来的,并且不会改变。
[[Scope]]
函数激活阶段
在函数激活阶段,也就是当调用一个函数的时候,会进入该函数的执行上下文,此时通过复制将函数的[[Scope]]属性来构建当前环境的作用域。随后在函数中的活动对象AO创建完成之后被推入当前执行上下文的最前端,构成该函数的作用域链。
AO
简单的来说:一个函数的作用域链,是由函数的活动对象和函数的内部属性[[Scope]]构成,用伪代码描述:
Scope = [AO, [[Scope]]]
举个例子:
var x = 10 function foo () { console.log(x) } function bar () { var x = 20 foo() // 10 } bar()
第一步,在创建函数的时候,先查找到当前所在的变量对象,很明显这里的变量对象是VO,也就是全局对象,将其存储在函数内部的[[Scope]]属性中,所以此时
VO
foo.[[Scope]] = [VO] bar.[[Scope]] = [VO]
第二步,当调用bar的时候,先复制bar.[[Scope]]来构建bar执行上下文的作用域链,此时
bar
bar.[[Scope]]
Scope = [bar.[[Scope]]] = [VO]
随后,bar的活动对象创AO(bar)建完成之后,此时将AO推入作用域链
AO(bar)
Scope = [AO(bar), Scope] = [AO, VO]
至此,函数bar的作用域链构建完成。
调用foo的时候和上面的流程类似,最终foo的作用域链如下:
foo
Scope = [AO(foo), VO]
由于在函数foo中查找不到变量x,所以会沿着作用域链向上查找,因此最终输出的是10。
x
10
http://www.cnblogs.com/TomXu/archive/2012/01/18/2312463.html
The text was updated successfully, but these errors were encountered:
No branches or pull requests
作用域链
这篇文章来讨论一下执行上下文中的另一个属性,作用域链。作用域链的本质是一个指向变量对象的指针列表。
函数的生命周期
函数的生命周期可以分为两个部分:函数创建和函数激活(即函数调用)。
函数创建
前面的文章我们知道,每个执行上下文都会有对应的变量对象。全局环境的变量对象一直存在,直到程序关闭。而函数中的局部的变量对象则是在函数执行的时候才会创建,函数执行结束后销毁。
在函数创建的时候,会预先创建一个包含上一级执行上下文变量对象的作用域,该作用域会保存在内部属性
[[Scope]]
中。这也意味着函数外部的作用域是在函数创建的时候就已经确定下来的,并且不会改变。函数激活阶段
在函数激活阶段,也就是当调用一个函数的时候,会进入该函数的执行上下文,此时通过复制将函数的
[[Scope]]
属性来构建当前环境的作用域。随后在函数中的活动对象AO
创建完成之后被推入当前执行上下文的最前端,构成该函数的作用域链。简单的来说:一个函数的作用域链,是由函数的活动对象和函数的内部属性
[[Scope]]
构成,用伪代码描述:举个例子:
第一步,在创建函数的时候,先查找到当前所在的变量对象,很明显这里的变量对象是
VO
,也就是全局对象,将其存储在函数内部的[[Scope]]
属性中,所以此时第二步,当调用
bar
的时候,先复制bar.[[Scope]]
来构建bar
执行上下文的作用域链,此时随后,
bar
的活动对象创AO(bar)
建完成之后,此时将AO
推入作用域链至此,函数
bar
的作用域链构建完成。调用
foo
的时候和上面的流程类似,最终foo
的作用域链如下:由于在函数
foo
中查找不到变量x
,所以会沿着作用域链向上查找,因此最终输出的是10
。总结
[[Scope]]
属性是在函数创建的时被存储下来的,并且是静态不变的,直到函数销毁。[[Scope]]
属性是所有父变量对象的层级链参考
http://www.cnblogs.com/TomXu/archive/2012/01/18/2312463.html
The text was updated successfully, but these errors were encountered: