呼叫棧

呼叫棧是一種機制,用於直譯器(例如網頁瀏覽器中的 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

呼叫棧一開始將是空的,上面的程式碼將像這樣執行:

  1. 忽略所有函式,直到它到達 greeting() 函式呼叫。

  2. greeting() 函式新增到呼叫棧列表中,我們得到:

    - greeting
    
  3. 執行 greeting() 函式內部的所有程式碼行。

  4. 到達 sayHi() 函式呼叫。

  5. sayHi() 函式新增到呼叫棧列表中,就像這樣:

    - sayHi
    - greeting
    
  6. 執行 sayHi() 函式內部的所有程式碼行,直到其結束。

  7. 將執行返回到呼叫 sayHi() 的那一行,並繼續執行 greeting() 函式的其餘部分。

  8. 從我們的呼叫棧列表中刪除 sayHi() 函式。現在呼叫棧看起來像:

    - greeting
    
  9. greeting() 函式內部的所有內容都已執行完畢後,返回到其呼叫行以繼續執行其餘的 JS 程式碼。

  10. 從呼叫棧列表中刪除 greeting() 函式。呼叫棧再次變空。

總之,我們從一個空的呼叫棧開始。每當我們呼叫一個函式時,它都會自動新增到呼叫棧中。一旦函式執行完其所有程式碼,它就會自動從呼叫棧中移除。最終,棧再次變空。

另見