(Day01) 執行環境與執行堆疊
執行環境 (Execution context)
在 JS 世界中執行環境是根據不同 function ,做區分的不同的函示,執行環境會是不同的。
直接用個簡單例子,就可以看出這個觀念:
1 | function FN1(){ |
如同上面範例中,FN2
函示中、以及全域底下是無法找到 FN1 中的 string
常數,值得一提的是 JS 最底層的執行環境,就是全域本身(window) 。
執行堆疊 (Execution Stack)
執行堆疊是和上面執行環境相關的觀念,一般狀況下,函示執行完畢,函示記憶體便會釋放,比如這個範例:
1 | function FN1(){ |
範例的執行順序就會是:
執行 FN1 函示 ⇒ FN1 函示執行完畢,釋放記憶體 ⇒ 執行 FN2 函示 ⇒ FN2 函示執行完畢,釋放記憶體 。
當然這是一般狀況,如果我們函示中又『呼叫』了另外的函示,那麼就會造成執行堆疊的狀況,比如這個範例:
1 | function FN1(parmNum){ |
這邊可以使用 chrome 瀏覽器的 Sources 功能來觀察 執行堆疊 狀況:
(這邊要注意的是圖中的 Call Stack 狀況,Call Stack 就是執行堆疊狀態)
從上面 GIF 可以發現,FN1()
呼叫了 FN2()
, 這種函示呼叫另一個函示時,Call Stack 就會一層一層疊起來,而這個堆疊順序是根據 『怎麼呼叫函示』有關,而非函示的宣告順序,因此根據程式碼執行堆疊順序就會是:FN1()
⇒ FN2()
⇒ FN3()
而上面有提到函示執行完畢,會將記憶體釋放,而堆疊後的函示釋放順序則不會是一般人預期中的:FN1()
⇒ FN2()
⇒ FN3()
而是由最後被執行的函示開始釋放,因此釋放的順序會是:FN3()
⇒ FN2()
⇒ FN1()
參考文獻
- JavaScript 核心篇 (六角學院)
- JavaScript 核心觀念(4)-執行環境與作用域-執行環境與執行堆疊