忽然很想了解「延遲 0 秒」的函式明明寫在文件上方,應該先被執行,但在 console 印出的結果,他還是被排在第二順位
全域執行環境 (Global execution context)
執行環境在建立時會有兩個階段
- 創造階段(Creation Phase)
- 執行階段(Execution Phase)
當完成創造階段後,便會進入執行階段,執行時會「從上到下,一行一行的執行程式」,而且會跳過函式內的程式碼,因為目前只是宣告函式並沒有馬上呼叫執行。
全域執行環境會被放在堆疊中的第一層,因為它是最早被建立的執行環境。
而這些堆疊起來的執行環境,稱為「執行堆疊(Execution Stack)」
堆疊(stack)
呼叫函式(Function)會形成一個執行環境的堆疊。
當呼叫bar時,會產生一個含有 bar的參數及區域變數的執行環境,而在bar呼叫了foo時,含有 foo參數及變數的第二個執行環境就會被置於堆疊的最上面。當foo回傳後,最上面的執行環境會被抽離堆疊(僅留下bar的呼叫執行環境)。然後當bar返回之後,堆疊就會清空。
JavaScript是單執行緒
簡單來說,就是「一次只能做一件事」
堆疊是有順序性的,堆疊相當於一棟大樓,越晚(越新)被建立的執行環境,就會被堆疊在大樓的越上層,反之,越早建立的執行環境,就會在大樓的越低層。
一旦堆疊建立起來,基於JavaScript是單執行緒的特性,它只能一次處理一件事,所以它會優先處理在堆疊頂端的執行環境;當函式被執行完並return,該執行環境就會自動從堆疊的頂端消失,接著JavaScript會接續著執行在堆疊中最頂端的執行環境,直到所有執行環境都完成任務、從堆疊中被移除。
零延遲(zero delays)
「零延遲」並非意味著回呼函式(callback function)會在 0 毫秒之後立刻執行。當使用延遲 0 毫秒參數來呼叫setTimeout函式並非示程式會過了該段時間就會執行,而是會參考佇列中等待的訊息數量。
「this is just a message」會在setTimeout的回呼訊息被執行之前被印出,因為該時間段參數是要求執行環境處理所需的最少等待時間,而非一個保證時間。