当代码在一个环境中执行时,会创建变量对象的一个作用域链(scope chain)。作用域链的用途用来查询变量。作用域链的前端始终是当前执行的代码所在环境的变量对象。如果这个环境是函数,则将其活动对象作为变量对象。作用域链中的下一个变量对象来自外部环境,而再下一个变量对象来自下一个外部环境。这样,一直延续到全局执行环境;全局执行环境的变量对象始终都是作用域链中的最后一个对象。
标识符解析是沿着作用域链一级一级第搜索标识符的过程。搜索过程始终从作用域链的前端开始,然后逐级地向后回溯,直到找到标识符为止。
让我们分析一段代码:
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
函数的执行顺序是fn->fn1->fn3->fn2 fn2中的a并没有在在当前作用域内声明,所以会沿着作用域链去它的上级作用域fn3去寻找a的声明。
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
函数的执行顺序是fn->fn1->fn3->fn2 fn2中的a并没有在在当前作用域内声明,而此时它的上一级作用域是全局作用域,所以最终输出1
网友评论