调用栈
**调用栈**是解释器(例如 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
调用栈在一开始将为空,上面的代码将按以下方式执行
- 忽略所有函数,直到到达
greeting()
函数调用。 - 将
greeting()
函数添加到调用栈列表中,我们得到- greeting
- 执行
greeting()
函数内部的所有代码行。 - 到达
sayHi()
函数调用。 - 将
sayHi()
函数添加到调用栈列表中,如下所示- sayHi - greeting
- 执行
sayHi()
函数内部的所有代码行,直到到达其末尾。 - 将执行返回到调用
sayHi()
的行,并继续执行greeting()
函数的其余部分。 - 从我们的调用栈列表中删除
sayHi()
函数。现在调用栈看起来像这样- greeting
- 当
greeting()
函数内部的所有内容都执行完毕后,返回到其调用行以继续执行 JS 代码的其余部分。 - 从调用栈列表中删除
greeting()
函数。再次,调用栈变为空。
总之,我们从一个空的调用栈开始。每当我们调用一个函数时,它都会自动添加到调用栈中。函数执行完其所有代码后,它会自动从调用栈中删除。最终,栈再次为空。