进阶篇:闭包的作用域链(18-2)
2019-07-16 本文已影响0人
饥人谷1904_陈俊锋
饥人谷学习进阶第 18 天
相关概念
- 执行上下文 executionContext
- 活动对象AO
- Scope属性
详细概念 请参看 进阶篇:作用域(链)&引用类型 (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