调用栈

调用栈是一种机制,用于解释器(例如网页浏览器中的 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() 函数。调用栈再次变空。

总之,我们从一个空的调用栈开始。每当我们调用一个函数时,它都会自动添加到调用栈中。一旦函数执行完其所有代码,它就会自动从调用栈中移除。最终,栈再次变空。

另见