调用栈

**调用栈**是解释器(例如 Web 浏览器中的 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()函数。再次,调用栈变为空。

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

另请参阅