在前端開發中,執行上下文 (Execution Context) 是理解 JavaScript 程式碼如何執行的關鍵概念。它決定了變數和函式的訪問範圍,以及程式碼執行的順序。 可以把它想象成一個容器,其中包含了當前程式碼執行所需的所有資訊。
一個執行上下文主要包含以下三個部分:
-
變數環境 (Variable Environment): 這部分儲存了在當前作用域內宣告的所有變數和函式宣告。在程式碼執行之前,變數會被建立並初始化(
var
型別的變數初始化為undefined
,let
和const
型別的變數不會初始化)。函式宣告會被完整地儲存,包括函式體。 -
詞法環境 (Lexical Environment): 詞法環境定義了當前作用域可以訪問的外部作用域。它透過一個指向外部作用域的指標來實現。這形成了作用域鏈 (Scope Chain),允許內部作用域訪問外部作用域的變數和函式。詞法環境是在程式碼編寫階段就確定的,由程式碼的巢狀結構決定,也稱為靜態作用域。
-
this
繫結 (This Binding):this
的值在執行上下文中確定,它指向當前程式碼執行的上下文物件。this
的繫結規則取決於函式的呼叫方式,例如全域性呼叫、方法呼叫、建構函式呼叫、以及使用apply
、call
或bind
方法呼叫。
執行上下文的型別:
主要有三種型別的執行上下文:
-
全域性執行上下文 (Global Execution Context): 每個 JavaScript 程式都有一個全域性執行上下文。它在程式碼開始執行之前建立,並且在整個程式的生命週期中都存在。全域性執行上下文中的
this
指向全域性物件 (在瀏覽器中是window
,在 Node.js 中是global
)。 -
函式執行上下文 (Function Execution Context): 每次呼叫一個函式都會建立一個新的函式執行上下文。函式執行上下文中的
this
的值取決於函式的呼叫方式。 -
Eval 執行上下文 (Eval Execution Context): 當程式碼在
eval()
函式內部執行時,會建立 Eval 執行上下文。現在已經不推薦使用eval()
,因為它存在安全風險和效能問題。
執行棧 (Execution Stack):
JavaScript 引擎使用執行棧來管理執行上下文。當程式碼開始執行時,全域性執行上下文會被推入棧中。每次呼叫一個函式,都會建立一個新的函式執行上下文並將其推入棧頂。當函式執行完畢後,其對應的執行上下文會從棧中彈出。當前正在執行的程式碼始終位於棧頂的執行上下文中。
理解執行上下文的重要性:
理解執行上下文對於理解 JavaScript 的核心概念至關重要,例如:
- 作用域和作用域鏈: 執行上下文定義了變數和函式的訪問範圍。
- 閉包: 閉包的形成與詞法環境密切相關。
this
關鍵字:this
的值在執行上下文中確定。- 變數提升 (Hoisting): 變數和函式宣告在執行上下文建立階段會被提升。
總而言之,執行上下文是 JavaScript 中一個非常重要的概念,理解它有助於我們更好地理解 JavaScript 程式碼的執行機制,編寫更有效和更易於維護的程式碼。