调用栈
调用栈是一种机制,用于解释器(例如网页浏览器中的 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()函数。调用栈再次变空。
总之,我们从一个空的调用栈开始。每当我们调用一个函数时,它都会自动添加到调用栈中。一旦函数执行完其所有代码,它就会自动从调用栈中移除。最终,栈再次变空。