- 作用域:定义这个变量的区域
- 作用域链:当前活动对象,加上包含它的所有活动对象
- 作用域链的作用:是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向上访问
作用域
function factory() {
let name = 'person';
let intro = function(){
alert('I am ' + name);
}
return intro;
}
function app(para){
let name = para;
let func = factory();
func(); //'I am person'
}
app('people');
JavaScript中的函数运行在它们被定义的作用域里,而不是它们被执行的作用域里
作用域链
- 变量对象VO分为:全局上下文VO和函数上下文AO
- 作用域链:本质上是一个指向变量对象的指针列表,它只是引用但不实际包含变量对象
Scope = AO|VO + [[Scope]]
-
[[Scope]]
是函数的一个属性,处于当前函数上下文之上,在函数创建时存于其中
let x = 10;
function foo() {
let y = 20;
function bar() {
let z = 30;
alert(x + y + z);
}
bar();
}
foo(); // 60
全局上下文的变量对象是
globalContext.VO === Global = {
x: 10
foo: <reference to function>
};
在foo
创建时,foo
的[[scope]]
属性是
foo.[[Scope]] = [
globalContext.VO
];
在foo
激活时(进入上下文),foo
上下文的活动对象是
fooContext.AO = {
y: 20,
bar: <reference to function>
};
所以,foo
上下文的作用域链为
fooContext.Scope = fooContext.AO + foo.[[Scope]] = [
fooContext.AO, //y=20
globalContext.VO //x=10
];
函数bar
创建时,其[[scope]]
为
bar.[[Scope]] = [
fooContext.AO,
globalContext.VO
];
bar
激活时,“bar”上下文的活动对象为
barContext.AO = {
z: 30
};
bar
上下文的作用域链为
barContext.Scope = barContext.AO + bar.[[Scope]] = [
barContext.AO, //x=30
fooContext.AO, //y=20
globalContext.VO //x=10
];
总结
- 函数
bar
的作用域链里可以访问x,y,z
- 函数
foo
的作用域链里可以访问x,y