呼叫棧
呼叫棧是一種機制,用於直譯器(例如網頁瀏覽器中的 JavaScript 直譯器)跟蹤其在呼叫多個函式的指令碼中的位置——當前正在執行哪個函式,以及從該函式內部呼叫了哪些函式等等。
- 當指令碼呼叫函式時,直譯器會將其新增到呼叫棧中,然後開始執行該函式。
- 由該函式呼叫的任何函式都會被進一步新增到呼叫棧中,並在其呼叫到達時執行。
- 噹噹前函式完成時,直譯器會將其從棧中取出,並在上次程式碼列表中中斷的地方恢復執行。
- 如果棧佔用的空間超過了其分配的空間,就會丟擲“棧溢位”錯誤。
示例
js
function greeting() {
// [1] Some code here
sayHi();
// [2] Some code here
}
function sayHi() {
return "Hi!";
}
// Invoke the `greeting` function
greeting();
// [3] Some code here
呼叫棧一開始將是空的,上面的程式碼將像這樣執行:
-
忽略所有函式,直到它到達
greeting()函式呼叫。 -
將
greeting()函式新增到呼叫棧列表中,我們得到:- greeting
-
執行
greeting()函式內部的所有程式碼行。 -
到達
sayHi()函式呼叫。 -
將
sayHi()函式新增到呼叫棧列表中,就像這樣:- sayHi - greeting
-
執行
sayHi()函式內部的所有程式碼行,直到其結束。 -
將執行返回到呼叫
sayHi()的那一行,並繼續執行greeting()函式的其餘部分。 -
從我們的呼叫棧列表中刪除
sayHi()函式。現在呼叫棧看起來像:- greeting
-
當
greeting()函式內部的所有內容都已執行完畢後,返回到其呼叫行以繼續執行其餘的 JS 程式碼。 -
從呼叫棧列表中刪除
greeting()函式。呼叫棧再次變空。
總之,我們從一個空的呼叫棧開始。每當我們呼叫一個函式時,它都會自動新增到呼叫棧中。一旦函式執行完其所有程式碼,它就會自動從呼叫棧中移除。最終,棧再次變空。