当代码在一个环境中执行时,会创建变量对象的一个作用域链(scope chain)。作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有权访问。作用域的前端,始终都是当前执行的代码所在环境的变量对象。
如果这个环境是函数,则将其活动对象(activation)作为变量对象。活动对象最开始只包含一个变量,即arguments对象(这个对象在全局环境中是不存在的)。
var color = "blue";
function changeColor(){
var anotherColor = "red";
function swapColors(){
var tempColor = anotherColor;
anotherColor = color;
color = tempColor;
//这里可以访问color,tempColor,anotherColor
}//这里可以访问color,anotherColor,但不能访问tempColor
}//这里只能访问color
changeColor();
在本例中,内部环境可以通过作用域链访问所有的外部环境,但外部环境不能访问内部环境中的任何变量和函数
在函数执行时,如何搜索作用域链
1.先从自己内部找变量
2.如果找不到,再从创建当前函数所在的作用域去找, 以此往上
3.注意找的是变量的当前的状态
试一试:
例1
var a = 1
function fn1(){
function fn2(){
console.log(a)
}
function fn3(){
var a = 4
fn2()
}
var a = 2
return fn3
}
var fn = fn1()
fn() //输出2
例2
var a = 1
function fn1(){
function fn3(){
var a = 4
fn2()
}
var a = 2
return fn3
}
function fn2(){
console.log(a)
}
var fn = fn1()
fn() //输出1
例3
var a = 1
function fn1(){
function fn3(){
function fn2(){
console.log(a)
}
fn2()
var a = 4
}
var a = 2
return fn3
}
var fn = fn1()
fn() //输出undefined