🚜

调用栈

This wiki is built in Notion. Here are all the tips you need to contribute.

什么情况下, 代码会在执行之前就进行编译并创建执行上下文

  1. 执行全局代码的时候, 会编译全局代码并创建全局执行上下文 (在整个页面生命周期内, 全局执行上下文只有一份)
  1. 调用一个函数的时候, 函数体内的代码会被编译, 并创建函数执行上下文 (一般情况下, 函数执行结束之后, 创建的函数执行上下文就会被销毁)
  1. 当使用 eval 函数的时候, eval 的代码也会被编译, 并创建执行上下文
 

什么是调用栈

调用栈就是用来管理函数调用关系的一种数据结构
 

调用栈如何工作

var a = 2
function add(b,c){
  return b+c
}
function addAll(b,c){
var d = 10
result = add(b,c)
return  a+result+d
}
addAll(3,6)

第一步, 创建全局上下文, 并将其压入栈底

notion image
执行上下文压入调用栈后, JS 引擎就开始执行全局代码
首先会执行 a=2 赋值操作, 执行完语句会将全局上下文变量环境中的 a 的值设置为 2

第二步, 调用 addAll 函数

notion image
addAll 函数的执行上下文创建好之后, 便进入了函数代码的执行阶段
先执行 d=10 的赋值操作, 执行语句会将 addAll 函数执行上下文中的 d 由 undefined 变成 10
 

第三步, 执行到 add 函数

同样会为 add 函数创建执行上下文, 并将其压入调用栈
notion image

第四步, 返回值, 出栈

当 add 函数返回时, 该函数的执行上下文就会从栈顶弹出, 并将 result 的值设置为 add 函数的返回值
notion image
紧接着 addAll 执行最后一个相加操作后并返回, addAll 的执行上下文也会从栈顶弹出, 此时调用栈中就只剩下全局上下文了
notion image
至此, 整个 JS 流程执行结束
 
 

如何利用好调用栈

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

notion image
notion image

栈溢出

调用栈是有大小的, 当入栈的执行上下文超过一定数目, JS 引擎就会报错, 栈溢出
避免栈溢出 1. 递归调用改造成其他形式 2. 加入定时器的方法来把当前任务拆分成其他很多小任务
 

思考题

优化一下代码, 解决栈溢出
function runStack (n) {
  if (n === 0) return 100;
  return runStack( n- 2);
}
runStack(50000)