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. 执行剩余的代码。
每当我们执行下面的代码时,它都会在调用堆栈中添加全局执行上下文。每当它从全局执行竞赛中调用任何函数时,它都会将该函数添加到调用堆栈中,并首先开始执行该函数。
当从特定函数调用另一个函数时,该函数将被添加到调用堆栈并获得执行优先级。
当特定函数的执行完成后,解释器会将其从调用堆栈中删除。
每当堆栈占用的空间超过其大小时,它就会引发 'stack overflow' 错误。
<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 程序只能有 1 个调用堆栈,并且一次可以执行一行。