进阶篇:闭包的作用域链(18-2)

2019-07-16  本文已影响0人  饥人谷1904_陈俊锋

饥人谷学习进阶第 18 天

相关概念

详细概念 请参看 进阶篇:作用域(链)&引用类型 (6)

范例一

var x = 10
bar()
function foo() {
    console.log(x)
}
function bar() {
    var x = 30
    foo()
}

执行过程

没有执行bar()之前

globalContext = { //全局作用域/全局上下文
    AO: { //活动对象
        x: 10
        foo: function
        bar: function
    },
    Scope: null //全局下找不到就不用再找了
}
//声明 foo 时,得到
foo.[[scope]] = globalContext.AO
//声明 bar 时,得到
bar.[[scope]] = globalContext.AO

注意:在当前执行上下文内声明的函数,这个函数的[[scope]]就执行当前执行上下文的AO

当调用 bar() 时,进入 bar 的执行上下文

barContext = {
    AO: {
        x: 30
    },
    Scope: bar.[[scope]] //globalContext.AO
}

当调用 foo() 时,进入 foo 的执行上下文

fooContext = {
    AO: {}
    Scope: foo.[[scope]] //globalContext.AO
}

当调用 foo() 时,先从 foo 执行上下文中的 AO 里找,找不到再从 foo 的[[scope]]里找,找到后即调用

所以最后 console.log(x) 输出的是 10

范例二

var x = 10
bar()
function bar() {
    var x = 30
    function foo() {
        console.log(x)
    }
    foo()
}

开始

globalContext = {
    AO: {
        x: 10
        bar: function
    },
    Scope: null
}
//声明 bar 时,得到
bar.[[scope]] = globalContext.AO

当调用 bar() 时,进入 bar 的执行上下文

barContext = {
    AO: {
        x: 30
        foo: function
    },
    Scope: bar.[[scope]]
}
//声明 foo 时,得到
foo.[[scope]] = barContext.AO

当调用 foo() 时,进入 foo 的执行上下文

fooContext = {
    AO: {}
    Scope: foo.[[scope]] //barContext.AO
}

当调用 foo() 时,先从 bar 执行上下文中的 AO 里找,找不到再从 bar 的[[scope]]里找,找到后即调用

所以最后 console.log(x) 输出的是 30

上一篇下一篇

猜你喜欢

热点阅读