JavaScript - 调用堆栈
JavaScript 引擎使用调用堆栈来管理执行上下文。它是 JavaScript 运行引擎跟踪 JavaScript 代码中函数调用的重要机制。JavaScript 调用堆栈的工作是在内部执行的,但了解 JavaScript 如何执行函数非常重要。
JavaScript 调用堆栈跟踪当前需要运行的函数或代码块。它采用 LIFO(后进先出)的方式工作。因此,任何添加到调用堆栈顶部的函数都会首先执行。
JavaScript 调用堆栈如何工作?
每当执行任何 JavaScript 代码时,它都会将全局执行上下文添加到脚本中。
调用任何函数时,JavaScript 引擎都会将该函数添加到调用堆栈中。之后,当您从外部函数调用任何嵌套函数时,它会在调用堆栈中添加一个嵌套函数。
当内部函数执行完成后,它会从调用堆栈中弹出该函数。接下来,它会执行外部函数并将其从调用堆栈中弹出。再次,它会开始在全局上下文中执行代码。
当调用堆栈为空时,脚本停止运行。
让我们通过示例来了解 JavaScript 调用堆栈。
function two() {
console.log("this is function two");
}
function one() {
two();
console.log("This is function one");
}
one();
上述代码将按如下方式执行。
1. 代码开始执行时,调用堆栈保持为空,直到执行到 one() 函数。
2. 将函数 one() 添加到调用堆栈中。现在,调用堆栈为 [one()]。
3. 执行函数 one() 的第一行,该代码调用函数 two()。
4. 将函数 two() 添加到调用堆栈中。现在,调用堆栈为 [two(), one()]。
5. 执行函数 two() 的所有行。
6. 回退执行函数 one() 的剩余代码行。
7. 从调用堆栈中删除函数 two()。现在,调用堆栈为 [one()]。
8. 开始执行函数 one() 的剩余代码。当函数 one() 执行完成后,JavaScript 引擎开始执行剩余代码。
9. 从调用栈中删除函数 one()。现在,调用栈为空。
10. 执行剩余代码。
示例
每当执行以下代码时,它都会在调用栈中添加全局执行上下文。每当它调用全局执行上下文中的任何函数时,它都会将该函数添加到调用栈,并首先开始执行该函数。
当从特定函数调用另一个函数时,该函数会被添加到调用栈并获得优先执行权。
当特定函数执行完成后,解释器会将其从调用栈中删除。
每当堆栈占用的空间超过其大小时,就会抛出"堆栈溢出"错误。
<html>
<body>
<h2> JavaScript - Call stack </h2>
<div id = "output"></div>
<script>
const output = document.getElementById("output");
function two() {
output.innerHTML += "two <br>";
}
function one() {
two();
output.innerHTML += "one <br>";
}
one();
</script>
</body>
</html>
JavaScript 调用堆栈溢出
每当调用堆栈的大小超过定义的大小时,就会发生调用堆栈溢出。通常,当递归函数没有退出点调用时,就会发生堆栈溢出。
例如,在下面的代码中,fib() 函数没有退出点。因此,它会抛出调用堆栈溢出错误。
function fib() {
fib();
}
fib();
JavaScript 是一种单线程编程语言。因此,它从上到下逐行运行代码。这意味着 JavaScript 程序只能有一个调用堆栈,并且每次只能执行一行。

