JavaScript 中的调用栈

2023/2/6 javascript

# 调用栈:为什么 JavaScript 代码会出现栈溢出?

哪些情况下代码才算是“一段”代码,才会在执行之前就进行编译并创建执行上下文。主要有以下 3 种情况:

  1. 当 JavaScript 执行全局代码的时候,会编译全局代码并创建全局执行上下文,而且在整个页面的生存周期内,全局执行上下文只有一份。

  2. 当调用一个函数的时候,函数体内的代码会被编译,并创建函数执行上下文,一般情况下,函数执行结束之后,创建的函数执行上下文会被销毁。

  3. 当使用 eval 函数的时候,eval 的代码也会被编译,并创建执行上下文。注:eval() 函数计算 JavaScript 字符串,并把它作为脚本代码来执行。

# 什么是 js 中的调用栈?

在执行上下文创建好后,JavaScript 引擎会将执行上下文压入栈中,通常把这种用来管理执行上下文的栈称为执行上下文栈,又称调用栈

调用栈是 JavaScript 引擎追踪函数执行的一个机制,当一次有多个函数被调用时,通过调用栈就能够追踪到哪个函数正在被执行以及各函数之间的调用关系。

# 在开发中,如何利用好调用栈?

  1. 利用浏览器查看调用栈的信息

当你执行一段复杂的代码时,你可能很难从代码文件中分析其调用关系,这时候你可以在你想要查看的函数中加入断点,然后当执行到该函数时,就可以查看该函数的调用栈了。

除了通过断点来查看调用栈,你还可以使用 console.trace() 来输出当前的函数调用关系。

  1. 栈溢出(Stack Overflow)

调用栈是有大小的,当入栈的执行上下文超过一定数目,JavaScript 引擎就会报错,我们把这种错误叫做栈溢出。如下代码:

function division(a, b) {
  return division(a, b);
}
console.log(division(1, 2));

抛出的错误信息为:超过了最大栈调用大小(Maximum call stack size exceeded)。报错原因:这个函数是递归的,并且没有任何终止条件,所以它会一直创建新的函数执行上下文,并反复将其压入栈中,但栈是有容量限制的,超过最大数量后就会出现栈溢出的错误。

理解了栈溢出原因后,你就可以使用一些方法来避免或者解决栈溢出的问题,比如把递归调用的形式改造成其他形式,或者使用加入定时器的方法来把当前任务拆分为其他很多小任务。

    我记得
    赵雷