執行環境與堆疊

JavaScript 一次只能做一件事情,他會依據 執行環境 (Execution Context) 來一一執行工作內容,本篇系列文會用舉例的方式,讓大家用簡單的方式瞭解這些艱深詞彙。

全域執行環境與函式

在一開始會登記一個函式在全域環境下(global context),然後這個全域環境下可以登記其他函式,然後每一段執行環境下會有屬於他的變數以及物件,如果找不到該執行環境的變數或物件,則會向外層尋找。

故事說明:小明是本作的主角,早上時固定會做幾件事情,一個是與老媽說早安,另一個則是吃早餐,老媽與早餐可能會換(?),所以他是可能會變動的,但大致上來說是說完早安,再去吃早餐。於是會在紙上紀錄下早上要做的事情。

早上要做的事情:

  • 變數
    • 媽:”老媽”
    • 早餐:”麵包”
  • 要做的事情 (function context)
    • 吃早餐
    • 說 ‘hi’
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function doMorningWork() {
// 從此 function 的大括號是另一個執行環境
var mom = "老媽";
var breakfast = "麵包";

function sayHi() {
// 說早安執行環境
return 'hi ' + mom;
}

function eatBreakfast() {
// 吃早餐執行環境
return '吃 ' + breakfast;
}

console.log('早安,' + sayHi() + ', ' + eatBreakfast());
}

doMorningWork(); // 執行

這個地方我們得到了三個執行環境(Execution Context),其中一個是 (global context),另外兩個則是在 global 下的 doMorningWork 內。

故事說明:小明得了一個症狀,每天早上都是全新的一天,他會忘記先前的人事物(簡直電影故事劇情,細節不重要),他會將每天該做的事情記錄下來,也分為主要任務及主要任務下的次要任務,並且把任務的相關人等寫下,並且一件一件事情完成它 (小明只有一個,一次只能做一件事情)。

他會依序將工作完成:

  1. 檢視一下工作任務有哪些
  2. 看完早上的任務後開始執行 doMorningWork()
    1. 接下來將會面對的人事物先存在大腦內 var ...
    2. 接下來他會面對第一個工作 sayHi()
      1. 這個工作沒有專屬的變數,於是他找主要任務的變數 mom
      2. 執行完成
    3. 做下一個任務…
  3. 他會將所有的任務完成,才會開始做下一個主要任務 (這個範例只有一個)

要做的事情往後會越來越多,小明會把要做的事情存在腦內,然後依據順序來執行。

糟糕的事情是,遇到他不知道該怎麼做下去的事情,他會卡在那邊一整天 (xxx is not defined)。

小明的筆記本與 JavaScript 有著接近的邏輯,有著一件一件要做的事情等待他去完成。

執行堆疊

在這個故事中也可以說明 JavaScript 的執行堆疊,一開始會先進入 global 執行環境,接下來再進入內層的環境,執行完的堆疊就會被釋放掉 (function 內的 return 即是完成),然後逐步地完成所有堆疊,最後將控制權交還給 Global。

每個執行堆疊都會一層一層地向內執行,等到都執行完以後才會回到外層執行下一個任務。

這段概念影響了什麼?

  1. JavaScript 由外而內執行,執行完才會進行下一個動作
  2. 如果其中一個環境卡住,那麼 JavaScript 就會掛掉(小明想不通)

另外,變數的作用域也與此有很大的關係,我們到下一章節來繼續介紹關於作用域 :)。