Execution Context
什麼是 Execution Context?
在 JavaScript 中,每當函式被呼叫時,JavaScript 引擎都會創建一個 Execution Context(執行上下文)來執行這個函式。Execution Context 包含了函式的執行環境,包括變數、函式、參數等。
Execution Context 有三種類型:
- Global Execution Context
- Function Execution Context
- Eval Execution Context
範例
以下是一個範例程式碼,展示了 Global Execution Context、Function Execution Context 和 Eval Execution Context:
// Global Execution Context
var globalVar = "I am a global variable";
function myFunction() {
// Function Execution Context
var functionVar = "I am a function variable";
console.log(globalVar); // 可以存取全域變數
console.log(functionVar); // 可以存取函數內部變數
// eval("var evalVar = 'I am a variable inside eval'; console.log(evalVar);");
// console.log(evalVar); // 由於 eval 是在同一個執行環境內,它創建的變數也可以在這裡存取
}
myFunction();
console.log(globalVar); // 可以在全域環境存取
// console.log(functionVar); // 會拋出錯誤,因為 functionVar 是函數內部的變數,無法在全域環境存取
// console.log(evalVar); // 會拋出錯誤,因為 evalVar 是在函數執行環境中被定義的變數
- Global Execution Context:
- 當這個程式開始執行時,首先創建的是全域執行環境。在這個環境中,我們定義了
globalVar
變數。
- 當這個程式開始執行時,首先創建的是全域執行環境。在這個環境中,我們定義了
- Function Execution Context:
- 當呼叫
myFunction()
時,JavaScript 創建一個新的執行環境,也就是函數執行環境。在這裡,我們定義了functionVar
變數。 - 在這個環境中,函數內部可以存取全域變數
globalVar
,但全域環境無法存取函數內部變數functionVar
。
- 當呼叫
- Eval Execution Context:
- 當執行
eval()
時,它會創建一個新的執行環境,但這個環境仍然屬於當前的函數執行環境。所以在eval
中定義的evalVar
變數也可以在該函數內部存取。
- 當執行
Execution Context 的生命週期
Execution Context 的生命週期可以分為以下幾個階段:
- Creation Phase(創建階段):當執行環境被創建時,會做以下三件事:
- 變數對象(Variable Object, VO) 被創建,並包含所有在這個環境內定義的變數、函數、參數。
- 作用域鏈(Scope Chain) 被建立,這是用來決定程式內部變數存取規則的機制。
- this 綁定,指向執行該代碼的對象。
- Execution Phase(執行階段):在這個階段,JavaScript 引擎會執行函數的程式碼,並根據程式碼中的變數和函數來更新變數環境和語法環境。
- Garbage Collection(垃圾回收):當 Execution Context 結束時,JavaScript 引擎會對其進行垃圾回收,釋放內存空間。
Execution Stack / Call Stack
Execution Stack(執行堆疊)是一個用來管理 Execution Context 的資料結構。當 JavaScript 引擎遇到一個函數執行時,它會將該函數的 Execution Context 推入執行堆疊的頂部,然後開始執行這個函數。當函數執行完畢後,它的 Execution Context 會從執行堆疊中彈出,JavaScript 引擎會繼續執行下一個 Execution Context。
執行堆疊是一個後進先出(Last In, First Out)的資料結構,這意味著最後進入的 Execution Context 會最先被執行。
範例
以下是一個簡單的範例,展示了執行堆疊的運作方式:
function firstFunction() {
console.log("Inside firstFunction");
secondFunction();
}
function secondFunction() {
console.log("Inside secondFunction");
}
firstFunction();
- 當程式開始執行時,首先創建了全域執行環境,並將
firstFunction
推入執行堆疊。 - 當
firstFunction
開始執行時,它會將secondFunction
推入執行堆疊。 - 當
secondFunction
執行完畢後,它會從執行堆疊中彈出。 - 然後
firstFunction
繼續執行,直到結束。