深刻學習js系列是本身階段性成長的見證,但願經過文章的形式更加嚴謹、客觀地梳理js的相關知識,也但願可以幫助更多的前端開發的朋友解決問題,期待咱們的共同進步。前端
若是以爲本系列不錯,歡迎點贊、評論、轉發,您的支持就是我堅持的最大動力。數組
在《深刻學習js之——執行上下文棧》中說過,當JavaScript代碼執行一段可執行代碼(executable code)時,會建立對應的執行上下文(execution context)微信
對於每個執行上下文,都有三個重要的屬性:閉包
變量對象(Variable object VO) 做用域鏈(Scope chain) thisapp
本文咱們結合着這三個部分的內容,講講執行上下文的具體處理過程。函數
在《深刻學習js之——詞法做用域和動態做用域》中,提出這樣一道思考題:post
// 思考題一:
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f();
}
checkscope();
// 思考題二:
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f;
}
checkscope()();
複製代碼
兩段代碼都會打印local scope
,可是仍是有些許差別的,本文就詳細的解析執行上下文棧和執行上下文的具體變化過程。學習
咱們分析第一段代碼:this
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f();
}
checkscope();
複製代碼
執行過程以下:spa
一、執行全局代碼,建立全局執行上下文,全局上下文被壓入執行上下文棧
ECStack = [
globalContext
];
複製代碼
二、全局上下文初始化
globalContext = {
VO: [global],
Scope: [globalContext.VO],
this: globalContext.VO
}
複製代碼
二、初始化的同時,checkscope 函數被建立,保存做用域鏈到函數內部的屬性[[scope]]
checkscope.[[scope]] = [
globalContext.VO
];
複製代碼
三、執行checkScope 函數,建立checkScope 函數執行上下文,checkScope 函數執行上下文被壓入執行上下文棧:
ECStack = [
checkscopeContext,
globalContext
];
複製代碼
四、checkscope 函數執行上下文初始化:
1.複製函數 [[scope]] 屬性建立做用域鏈, 2.用 arguments 建立活動對象, 3.初始化活動對象,即加入形參、函數聲明、變量聲明, 4.將活動對象壓入 checkscope 做用域鏈頂端,
同時 f 函數被建立,保存做用域鏈到 f 函數的內部屬性[[scope]]
checkscopeContext = {
AO: {
arguments: {
length: 0
},
scope: undefined,
f: reference to function f(){}
},
Scope: [AO, globalContext.VO],
this: undefined
}
複製代碼
五、執行f函數,建立 f 函數執行上下文,f 函數執行上下文被壓入執行上下文棧
ECStack = [
fContext,
checkscopeContext,
globalContext
]
複製代碼
六、f 函數執行上下文初始化, 如下跟第 4 步相同:
1.複製函數
[[scope]]
屬性建立做用域鏈 2.用 arguments 建立活動對象 3.初始化活動對象,即加入形參、函數聲明、變量聲明 4.將活動對象壓入 f 做用域鏈頂端
fContext = {
AO: {
arguments: {
length: 0
}
},
Scope: [AO, checkscopeContext.AO, globalContext.VO],
this: undefined
}
複製代碼
七、f 函數執行,沿着做用域鏈查找 scope 值,返回 scope 值
八、f 函數執行完畢,f 函數上下文從執行上下文棧中彈出
ECStack = [
checkscopeContext,
globalContext
]
複製代碼
九、checkscope 函數執行完畢,checkscope 執行上下文從執行上下文棧中彈出
ECStack = [
globalContext
]
複製代碼
歡迎添加個人我的微信討論技術和個體成長。
歡迎關注個人我的微信公衆號——指尖的宇宙,更多優質思考乾貨