先來複習一下,執行上下文的構成
bash
執行上下文函數
以前說了變量對象
,如今來講下另外兩個this
通俗地講,當聲明一個函數時,局部做用域一級一級向上包起來,就是做用域鏈。spa
咱們從函數定義到執行一步一步來講明code
當函數被定義的時候,會讀取函數內部的一個屬性,[[scope]]屬性來保存就會保存全部父變量對象到其中,能夠理解 [[scope]] 就是全部父變量對象的層級鏈對象
function a(){
function b(){
}
}
複製代碼
分析一下,當函數建立時,各自的[[scope]]爲
作用域
a.[[scope] = [
globalContext.VO
]
b.[[scope]] = [
aContext.AO,
globalContext.VO
];
複製代碼
當函數激活的時候,建立VO/AO。並將其加入做用域鏈的第一位,做用域鏈(scope)到如今就建立完畢了string
var global = '全局變量'
function abs(){
a = 1
console.log(a)
}
abs()
複製代碼
1.函數abs被建立,將做用域鏈保存到[[scope]]中
it
abs.[[scope]] = [
globalContext.VO
]
複製代碼
2.abs函數開始執行,此時建立abs函數的執行上下文,併入棧
io
ECstack = [
absContext
globalContext
]
複製代碼
3.abs作正式執行前的準備工做,將[[scope]]屬性做爲做用域鏈,此時的abs執行上下文
absContext = {
Scope: abs.[[scope]],
}
複製代碼
4.初始化變量對象,VO/AO
absContext = {
AO: {
arguments: {
length: 0
},
a: undefined
},
Scope:abs.[[scope]]
}
複製代碼
5.將活動對象AO加到做用域鏈的頂端
absContext = {
AO: {
arguments: {
length: 0
},
a: undefined
},
Scope:[AO,abs.[[scope]]]
}
複製代碼
至此,準備工做完成
6.隨着函數的進行,AO開始進行賦值工做
checkscopeContext = {
AO: {
arguments: {
length: 0
},
a: 1
},
Scope: [AO, [[Scope]]]
}
複製代碼
7.在做用域鏈中找到a的值並打印
8.abs執行完畢,abs的執行上下文棧彈出
ECstack = [
globalContext
]
複製代碼