iT邦幫忙

0

JavaScript的執行階段: Execution Context

為了知道那些常被拿來考觀念的專有名詞是哪裡來的,
這篇要先整理 JS的 Execution Context!

Execution Context 的定義


『當JS引擎執行一段程式碼(script)時,便會創造 execution contexts。』
『且每個execution context 包含兩個階段:創造階段 creation phase執行階段 execution phase。』

引用自JavaScript Tutorial Website的解釋:

When a JavaScript engine executes a script, it creates execution contexts. Each execution context has two phases: the creation phase and the execution phase.
(引用自 JavaScript Execution Context )

→ 也就是說,Execution contexts 包含了程式碼 創造物件 到 執行 的過程。

到這裡先記一個結論,接下來先繼續看實際上發生了什麼事。

Execution Context 的執行過程


所以Execution Context到底在做什麼?

在執行過程中,JS裡的物件會被初始化和給值。

假設現在JS要執行一個script,那麼他就會:

  1. 先產生Execution Context
  2. 進入創造階段 creation phase
  3. 完成creation phase,進入執行階段 execution phase。

在剛剛提到的定義裡,可以發現定義裡的execution context"s"是複數形,
由此可知會產生的execution context其實不只有一個,而程式碼會執行的execution context分為兩種:

  • Global Execution Context ( *Global 全域
  • Function Execution Context ( *Function 函數

並且,它們各自包含了 創造階段 creation phase執行階段 execution phase
所以這邊先畫個簡表,我們現在有的資訊大概長這樣:
https://ithelp.ithome.com.tw/upload/images/20210902/20129476Lne8evQG1H.png

而我們學習目標,就是要知道這段過程,哪個物件先創造? 什麼時候被指派? 被指派給誰?

知道重點是什麼就可以往下看了~

Global Execution Context


初次 執行一個script時,JS引擎會創造第一種 execution context,叫 Global Execution Context。

然後先進入 創造階段 creation phase :

https://ithelp.ithome.com.tw/upload/images/20210903/20129476UaNgShWsEt.png

  1. 創建 global object。( 如瀏覽器中的window object,或Node.js中的 global object。)
  2. 建立 scope (依照 closure 這個準則)。
  3. 創建 this object,並被綁定至 global object。
  4. variablesfunction 分配至記憶體,並初始化為 undefined。
    (這也是所謂的hoisting。)

講太多抽象的概念不好理解,讓我們假設一個求面積的程式碼範例:

let a = 3;

function area(s){
    return s * s;
}

let b = area(a);

console.log(b);

在這個階段,各object會被初始化,也就是程式碼會知道有這個object存在,但變數還不會被賦值。
因此 Global Execution Context在 creation phase 的狀態如下:

object value 備註
global object window 因為在瀏覽器里執行,因此global object 為 window
this window 這時的this也指向 window object
a undefined
area function(){...}
b undefined

接著,Global Execution Context 會來到 執行階段 execution phase:

這時JS的script便會逐行被執行,對variables給值,並執行function的呼叫(call)。

https://ithelp.ithome.com.tw/upload/images/20210903/20129476EODl3Rl0mw.png

( 補充 : JS是直譯式語言的一種,而直譯式語言的特色就是「逐行( line by line )」執行。相對於編譯式語言「先編譯再執行」的方式。)

let a = 3;  // a = 3

function area(s){
    return s * s;
}

let b = area(a); // 調用area(a)

console.log(b);

延續上方的例子,程式碼會逐行進行給值,因此a會被先assign為3,
接著要assign值給b,就必須進行function call,調用函數area()。

目前 Global Execution Context 在 execution phase 的狀態:

object value
global object window
this window
a 3
area function(){...}
b undefined

到這裡Global scope會先停下來,
然後進入到Function Execution Context的creation phase...

2. Function Execution Context


JS會創造複數的Execution Context,而第二種就是Function Execution Context。
而每次的 function call ,JS引擎也都會創造一個Function Execution Context。

Function Execution Context 的 創造階段 creation phase :

https://ithelp.ithome.com.tw/upload/images/20210903/20129476AUAToO6Tiw.png

和 Global Execution Context 的區別,引用文獻解釋的比較清楚 :

The Function Execution Context is similar to the Global Execution Context, but instead of creating the global object, it creates the arguments object that contains a reference to all the parameters passed into the function.
(引用自 JavaScript Execution Context )

簡而言之,Execution Context在 creation phase 創造的不是window,而是欲傳進函式的參數arguments物件。

於是我們在 Function Execution Context 在 creation phase 會變成下列的狀態:

object value
global object arguments
this window
s undefined

因為已經是Function Execution Context,global object會變為arguments,而參數s則被初始化為undefined。

然後進到 Function Execution Context 的 execution phase :

object value
global object arguments
this window
s 3

最後area(s)計算完成,便會回傳數值並assign給 b。

let a = 3;

function area(s){
    return s * s;
}

let b = area(a);

console.log(b);  // output: 9

從上面的敘述中,可以知道執行程式碼的時候創造了非常多的execution contexts,無論是Global EC或 Function EC 的執行,都會遵照被稱為 Call stack 資料結構。而資料結構就是之後文章的範疇了!


最後~

幫今天的文章畫重點:

  1. Execution context即為程式碼創造物件到執行的過程
  2. 過程分為 Global EC 和 Function EC 兩種。
  3. 兩者的區別為: Global EC創造的Global Object為window,Function EC創造的Global Object則為arguments

我寫了一張簡表,記憶JS的Execution Context執行和object的創建順序。

Global EC

C. window obj. → scope ( follow closure ) → this → Hoisting
E. follow Call stack

Function EC

C. scope chain → this → Hoisting
E. follow Call stack

  • EC = Execution Context.
  • C. = creation phase
  • E. = execution phase

之後整理專有名詞就可以更了解各個階段會出什麼事了

【如內文有誤還請不吝指教>< 並感謝閱覽至此的各位:D 】

---正文結束---

這篇是在發scope之前打好的,考慮了一下要不要跟鐵人賽發在一起,但實在太文不對題了所以還是獨立成一篇。
我覺得,發表文章在所有人都能看見的地方,是件蠻需要勇氣的事:(敬佩這裡所有的作者。


尚未有邦友留言

立即登入留言