作用域链
当函数被执行,便进入了自己的执行上下文,
该执行上下文中的变量若并没有被找到,
就会往上一层的作用域中去查找。
直到该作用域的顶层(一般为全局环境中)
JS权威指南中有一句很精辟的描述: ”JavaScript中的函数运行在它们被定义的作用域里,而不是它们被执行的作用域里.”
由上可知,作用域链的规则确定,是函数在哪里声明在地方,而非被执行的作用域中。
可以将此过程理解为,js引擎在解析js代码的时候就确定了函数的作用域链规则,而非是执行时产生的执行上下文而确定的作用域链。
函数被声明时
当函数被声明的时候,其函数内部有一个[[scope]]的属性,里面保存了该父作用域链级规则。
函数声明和执行的过程
以下为例
var scope = "global scope";
function checkscope(){
var scope2 = 'local scope';
return scope2;
}
checkscope();
- checkscope函数被创建时,作用域链相关规则被保存到内部属性[[scope]]中
checkscope.[[scope]] = [
globalContext.VO
];
-
执行checkscope函数,checkscope函数创建上下文(
checkscopeContext
)。checkscopeContext
被push进执行上下文栈中,以便执行代码。 -
checkscope函数并不马上执行,而是初始化活动对象,加入形参、函数声明、变量声明,复制作用域链并将活动对象压入 checkscope 作用域链顶端
checkscopeContext = {
AO: {
arguments: {
length: 0
},
scope2: undefined
},
Scope: checkscope.[[scope]],
}
将活动对象压入 checkscope 作用域链顶端
checkscopeContext = {
AO: {
arguments: {
length: 0
},
scope2: undefined
},
Scope: [AO, [[Scope]]]
}
- 始执行函数,随着函数的执行,修改 AO(变量对象) 的属性值
checkscopeContext = {
AO: {
arguments: {
length: 0
},
scope2: 'local scope'
},
Scope: [AO, [[Scope]]]
}
- 执行完函数,并从执行上下文栈中弹出。
作用域和执行上下文
- 作用域规定了函数内部变量,和内部函数的可访问范围。js没有块级作用域,当生命一个函数的时候,就产生了一个局部作用域。是一套规则
- 而执行上下文是,当函数在执行的时候,不仅仅是作用域和作用域链的访问规则。而是包括活动变量,形参等等的AO的环境。
网友评论