为了更好的理解作用域链,先做些准备工作
1.作用域
在JavaScript中,我们可以将作用域定义为一套规则,这套规则用来管理引擎如何在当前作用域以及嵌套的子作用域中根据标识符(这里的标识符,指的是变量名或者函数名)名称进行变量查找。
javascript中的作用域有全局作用域和局部作用域两种,局部作用域又称为函数作用域。
全局作用域
在代码中任何地方都能访问到的对象拥有全局作用域
var a = "tsrot";
function hello(){
alert(a);
}
function sayHello(){
hello();
}
alert(a); //能访问到tsrot
hello(); //能访问到tsrot
sayHello(); //能访问到hello函数,然后也能访问到tsrot
局部作用域(函数作用域)
局部作用域在函数内创建,在函数内可访问,函数外不可访问。
function hello(){
var a = "tsrot";
alert(a);
}
hello(); //函数内可访问到tsrot
alert(a); //error not defined
作用域链
函数在调用激活时,会开始创建对应的执行上下文,在执行上下文生成的过程中,变量对象,作用域链,以及this的值会分别被确定。
作用域链,是由当前环境与上层环境的一系列变量对象组成,它保证了当前执行环境对符合访问权限的变量和函数的有序访问。
作用域链指示了函数执行时按照什么样顺序去访问需要的变量,
具体过程如下例子:
var a = 20;
function test() {
var b = a + 10;
function innerTest() {
var c = 10;
return b + c;
}
return innerTest();
}
test();
在上面的例子中,全局,函数test,函数innerTest的执行上下文先后创建。我们设定他们的变量对象分别为VO(global),VO(test), VO(innerTest)。而innerTest的作用域链,则同时包含了这三个变量对象,所以innerTest的执行上下文生成的作用域链可如下表示。
VO(innerTest) ==> VO(test) ==> VO(global)
先在VO(innerTest)里面找到c,但没有找到b,于是向上一级找,在 VO(test)里面找到b,最后在全局VO(global)找到a
即函数在访问变量时,先在当前执行上下文寻找,找不到再向上一级寻找,直至全局上下文。