js 变量对象 作用域链
可执行代码:全局、函数、eval
执行代码时创建的上下文类型:全局上下文、函数上下文、eval上下文
执行上下文(EC)属性:变量对象(vo)、this、作用域链(sc)
执行上下文栈
变量对象
用来存储:变量、声明式函数、形参
- 全局对象:变量、声明式函数都存在window对象里面
激活对象:Arguments Object
- callee
- length
- [0]……[length-1]
变量实例化
优先级:声明式函数>函数形参>变量
(实例化时添加的变量不可删)
var a=10; delate //不可删
window.a; delate //可删
代码执行步骤:
- 进入上下文
- 初始化this 作用域链 变量对象
- 变量实例化
- 代码执行
作用域链
作用域链可以看做一个数组
- 全局上下文的作用域链 [全局对象]
- 函数上下文的作用域链 [当前激活对象+ function.[[scope]] ]
with 可以临时改变作用域链,因为多查找了一次变量,可能导致效率变低。
用一个例子来描述一下代码执行过程
EC:Execution Context 上下文
VO:variable objec 变量对象
SC:scope chain 作用域链
AO:activation object 激活对象
var y = 10;
function test(){
var y = 2;
return function(){
alert(y);
}
}
var fun = test();
fun();
创建上下文阶段
初始化this、变量对象、作用域链
global EC={ VO: { test : test_fun_objcet, y : undefined, fun : undefined }, this : window, SC : [window] }
变量实例化
global EC={ VO: { test : test_fun_objcet, y : 10, fun : test_fun_objcet }, this : window, SC : [window] }
此时的上下文栈
代码执行阶段
执行fun() ,即test函数,同样是先创建test的上下文,初始化this、变量对象、作用域链
test EC={ VO: { y : undefined }, this : window, SC : [testAO,window] //SC = [ 当前激活对象 + function.[[scope]] ] //其中激活对象是 testAO //function.[[scope]]是函数创建时所在的SC,即[window] }
此时的上下文栈
变量实例化
test EC={ VO: { y : 2 }, this : window, SC :[testAO,window] }
test执行阶段
返回匿名函数,创建匿名(anonymous)函数的上下文
anonymous EC={ VO: { }, this : window, SC : [anonymousAO,testAO, window] //SC = [ 当前激活对象 + function.[[scope]] ] //其中激活对象是 anonymousAO //function.[[scope]]是函数创建时所在的SC,即[testAO,window] }
此时的上下文栈
- 该匿名函数没有声明式函数、形参、变量,所以进入执行阶段
alert(y), 在当前的SC中查找y,当前的SC=[anonymousAO,testAO, window],anonymousAO中没有y,testAO中y=2,所以弹出结果是 2。
end
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。