執行上下文也叫執行環境?爲什麼呢就讓我這個英語zz來解釋下
context:環境; 上下文
執行環境:
執行環境中定義了變量或函數有權訪問的其他數據,決定了他們給各自行爲,每個執行環境都有一個與之關聯的變量對象,環境中定義的所有變量和函數都保持在這個對象中,雖然我們無法訪問到這個對象,但是解析器可以在處理數據的時候在後臺使用他
執行上下文類型:
- 全局執行上下文
- 函數執行上下文 : 每當一個函數被調用時, 都會爲該函數創建一個新的上下文。每個函數都有它自己的執行上下文,不過是在函數被調用時創建的。函數上下文可以有任意多個。每當一個新的執行上下文被創建,它會按定義的順序,在執行棧中(將在後文討論)執行一系列步驟。
- Eval 函數執行上下文 — 執行在
eval
函數內部的代碼也會有它屬於自己的執行上下文
執行棧
執行棧,也就是在其它編程語言中所說的“調用棧”,是一種擁有 LIFO(後進先出)數據結構的棧,被用來存儲代碼運行時創建的所有執行上下文
後進先出:也就是隻有一個出口(數組開頭的位置),後進的執行上下文也是離空最近的,所以就先出
當 JavaScript 引擎第一次遇到你的腳本時,它會創建一個全局的執行上下文並且壓入當前執行棧。每當引擎遇到一個函數調用,它會爲該函數創建一個新的執行上下文並壓入棧的頂部。
引擎會執行那些執行上下文位於棧頂的函數。當該函數執行結束時,執行上下文從棧中彈出,控制流程到達當前棧中的下一個上下文
let a = 'Hello World!';
function first() {
console.log('Inside first function');
second();
console.log('Again inside first function');
}
function second() {
console.log('Inside second function');
}
first();
console.log('Inside Global Execution Context');
1:只有全局執行上下文
2:first()函數執行,執行棧中添加first()函數的執行上下文
3:在first函數執行的過程中Second函數執行了,second函數的執行上下文加入到執行棧中
4:Second函數執行完畢,移除執行棧
5:Frist()函數執行完畢移除執行棧
怎麼創建執行上下文?
在 JavaScript 代碼執行前,執行上下文將經歷創建階段。在創建階段會發生三件事:
- this 值的決定,即我們所熟知的 This 綁定。
- 創建詞法環境組件。
- 創建變量環境組件。
ExecutionContext = {
ThisBinding = <this value>,
LexicalEnvironment = { ... },
VariableEnvironment = { ... },
}
This 綁定:
在全局執行上下文中,this
的值指向全局對象。(在瀏覽器中,this
引用 Window 對象)。
在函數執行上下文中,this
的值取決於該函數是如何被調用的。如果它被一個引用對象調用,那麼 this
會被設置成那個對象,否則 this
的值被設置爲全局對象或者 undefined
(在嚴格模式下)
詞法環境和變量環境
在詞法環境和變量環境的內部有兩個組件:(1) 環境記錄器和 (2) 一個外部環境的引用。
(1) 環境記錄器:存儲變量和函數聲明的實際位置
(2) 一個外部環境的引用:和它可以訪問其父級詞法環境(作用域)
但是有2種詞法環境和變量環境類型一個是全局的一個是函數的分2中不同的情況
注意 — 對於函數環境,聲明式(函數)環境記錄器還包含了一個傳遞給函數的 arguments
對象(此對象存儲索引和參數的映射)和傳遞給函數的參數的 length。
詞法環境和變量環境(區別)
在 ES6 中,詞法環境組件和變量環境的一個不同就是前者被用來存儲函數聲明和變量(let
和 const
)綁定,而後者只用來存儲 var
變量綁定。
例子:
let a = 20;
const b = 30;
var c;
function multiply(e, f) {
var g = 20;
return e * f * g;
}
c = multiply(20, 30);
解析:
// 全局
GlobalExectionContext = {
// 詞法環境
LexicalEnvironment: {
EnvironmentRecord: {
Type: "Object",
// 在這裏綁定標識符
a: < uninitialized >,
b: < uninitialized >,
multiply: < func >
}
ThisBinding: <Global Object>, // this
outer: <null> // 外部環境引用
},
// 變量環境
VariableEnvironment: {
EnvironmentRecord: {
Type: "Object",
// 在這裏綁定標識符
c: undefined,
}
outer: <null> // 外部環境引用
}
}
// 函數
FunctionExectionContext = {
// 詞法環境
LexicalEnvironment: {
EnvironmentRecord: {
Type: "Declarative",
// 在這裏綁定標識符
Arguments: {0: 20, 1: 30, length: 2}, // 函數的專屬 arguments
},
ThisBinding: <Global Object>, // this
outer: <GlobalLexicalEnvironment> // 外部環境引用
},
// 變量環境
VariableEnvironment: {
EnvironmentRecord: {
Type: "Declarative",
// 在這裏綁定標識符
g: undefined
},
outer: <GlobalLexicalEnvironment> // 外部環境引用
}
}
原作者更新了部分內容,將this bindng歸入詞法環境中了,