執行上下文和執行上下文堆棧

因爲想弄透閉包,所以想研究研究作用域鏈的,但是這兩天在查資料的過程中發現原來作用域鏈的背後還有更需要深入瞭解的知識,就是本文要記的知識點:執行上下文和執行上下文堆棧。理解了這個就更更方便理解作用域鏈以及之後的閉包啦。(剛開始看的時候,有點暈菜的感覺,寫的不好或有誤的地方,還請指出)。

一、執行上下文(execution context)

  1. 定義很簡單
    在文章ECMA-262-3 in detail. Chapter 1. Execution Contexts. 中的定義是:

Every time when control is transferred to ECMAScript executable code, control is entered an execution context.

每次控制器轉到ECMAScript可執行程序的時候,控制器進入執行上下文。

EExecution context (abbreviated form — EC) is the abstract concept used by ECMA-262 specification for typification and differentiation of an executable code.

執行上下文(簡稱-EC)是ECMA-262定義的一個抽象概念,用來和可執行代碼進行區分。上面提到的文章中寫到可能是ECMAScript引擎考慮的問題。
2. 理解

這個定義並沒有實質內容的定義,execution context也解釋爲執行環境(自我感覺比上下文好理解一些)。那麼根據這個定義便可以這麼理解:每個可執行代碼,都會有一個自己的執行上下文(EC),比如全局的JS代碼(可能存在函數實例,不包括函數體內的代碼)會有個全局的上下文(global context),對於函數實例的每次執行(是實例不是定義,包括函數被遞歸調用或作爲構造函數)都會有一個函數執行的上下文(function context,每次調用時的函數上下文都不同),同樣的,這個函數上下文不包括其內部函數的代碼(inner functions)。

比如下面這段代碼:

var a = "123";
function fun(arg){
var b = arg;
}
fun(a);
fun("o2");

上下文情況如圖(這只是我自己理解的情況,不代表真實情況)

執行上下文

當解釋器進入這段js代碼之後,進入全局代碼的globalContext,globalContext可能包含變量,函數聲明,可能還有其他屬性等等 ,當js代碼執行到fun(a)這個函數實例時,進入到這個函數實例的functionContext,functionContext可能包含傳入參數,arguments,自己的變量,還有其他屬性等,這兩個執行上下文有關係,但不是從屬關係。

在js代碼中有另一個函數實例,在fun(a)之後還有個fun(“o2”),執行到fun(“o2”)時,會進入另一個函數的上下文functionContext2,裏面的參數爲“o2”,變量b 等於 “o2”,這兩個函數上下文是兩個不同的上下文,以此類推同一個函數的每個實例的上下文都是不同的。

參考文章JavaScript. The core. 對執行上下文的解釋和圖示。

一個執行上下文可以抽象的表示爲一個簡單的對象。如下圖所示
Execution context
An execution context structure.

每個上下文對象都有一系列的必需的屬性,稱爲上下文狀態,用來追蹤相關代碼的執行情況。上面圖中有三個屬性:variable object(變量對象),this value(this值),scope chain(作用域鏈),除了這個三個屬性,在不同的情況下,執行上下文對象可能還有其他的屬性。

二、執行上下文堆棧(Execution context stack)

執行上下文直接的關係可以用堆棧來表示,一個執行上下文可以激活另一個執行上下文,比如進入js全局程序之後,進入全局上下文,在全局上下文運行程序的過程中,如果遇到函數調用,那麼就會激活對應的函數上下文,並進入這個函數上下文中運行代碼,當這個函數執行結束後,就會退出這個函數上下文,並重新回到全局上下文,直到整個程序結束(或拋出異常)就退出全局上下文。
這一過程在邏輯上可以看做堆棧。不過全局上下文始終位於堆棧底部,而堆棧頂部是當前活動的執行山下文,堆棧在進入和退出上下文的時候執行推入和彈出。
如下圖爲一個函數上下文(EC1)和全局上下文(Global EC)在堆棧中的執行過程。
這裏寫圖片描述

程序開始後,進入全局上行文,將Global EC push到堆棧底部,執行程序的一系列操作,遇到函數1時,進入函數上下文EC1,並將EC1 push到堆棧中,執行函數的一系列操作,函數執行結束後,pop出EC1,回到Global EC繼續執行全局上下文,直到程序結束,pop出Global EC。

參考文獻

  1. ECMA-262-3 in detail. Chapter 1. Execution Contexts.
  2. JavaScript. The core.
  3. 深入理解JavaScript系列(11):執行上下文(Execution Contexts)
  4. 深入理解JavaScript系列(10):JavaScript核心(晉級高手必讀篇)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章