當 JS 引擎處理一段腳本內容的時候,它是以怎樣的順序解析和執行的?腳本中的那些變量是何時被定義的?它們之間錯綜復雜的訪問關系又是怎樣創建和鏈接的?要解釋這些問題,就必須了解 JS 執行上下文的概念。
JavaScript引擎: JavaScript引擎是一個計算機程序,它接收JavaScript源代碼并將其編譯成CPU可以理解的二進制指令(機器碼)。JavaScript引擎通常是由瀏覽器供應商開發的,每一個主流瀏覽器都有一個自己開發的引擎。如:谷歌Chrome瀏覽器的V8引擎,Firefox的SpiderMonkey和IE的Chakra。
所有JavaScript代碼都需要在某種環境中托管運行。在大多數情況下,網絡瀏覽器就是這個環境。瀏覽器的JavaScript引擎會創造一個特殊的環境來處理這些JavaScript代碼的轉換和執行。
執行上下文的基本概念
執行上下文(Execution Context) 是 ECMAScript 規范中用于管理代碼執行環境的抽象機制,定義了變量、函數和 this 值的作用域規則。
每個執行上下文由以下三個核心組件構成:詞法環境(Lexical Environment)、變量環境(Variable Environment)和 This 綁定(ThisBinding)。
詞法環境:(Lexical Environment) 詞法環境是一種規范類型,用于根據 ECMAScript 代碼的詞法嵌套結構,將標識符與特定變量和函數關聯起來。簡單地理解,詞法環境用于存儲變量和函數的標識符綁定,即變量名與值的映射關系。其包含兩個部分,分別是環境記錄器和外部環境的引用。環境記錄(Environment Record)用于實際存儲變量名和值的映射(如 let a = 1 會記錄為 a → 1),是具體存儲變量和函數定義的對象。外部引用(Outer Reference)是指向外層詞法環境的指針,用于形成作用域鏈。
變量環境(Variable Environment): 變量環境是一種詞法環境,其環境記錄保存由 VariableStatements(即 var 聲明)創建的綁定。在 ES6 之后,變量環境是詞法環境的一種特例,兩者通常指向同一對象,但規范中仍保留區分以兼容舊代碼。
This 綁定(ThisBinding): this 綁定是一個值,用作當前執行上下文代碼的接收者。this 值在運行時根據函數調用方式確定(如全局調用、方法調用、構造函數調用等)。
ECMA-262 第 10 版(2024)
- “An execution context is a specification device that is used to track the runtime evaluation of code by an ECMAScript implementation.”(執行上下文是一種規范機制,用于跟蹤 ECMAScript 實現對代碼的運行時評估。)
- “A Lexical Environment is a specification type used to define the association of Identifiers to specific variables and functions based on the lexical nesting structure of ECMAScript code.”(詞法環境是一種規范類型,用于根據 ECMAScript 代碼的詞法嵌套結構,將標識符與特定變量和函數關聯起來。)
- “A Variable Environment is a Lexical Environment whose Environment Record holds bindings created by VariableStatements.”(變量環境是一種詞法環境,其環境記錄保存由 VariableStatements(即 var 聲明)創建的綁定。)
- “The this binding is a value that is used as the receiver for the current execution context’s code.”
(this 綁定是一個值,