调用栈(call stack)
JavaScript中有很多的函数,经常会出现在一个函数中调用另外一个函数的情况,调用栈就是用来管理函数调用关系的栈。 因此要搞明白调用栈,就要先搞明白函数调用和栈结构。
栈结构
栈就是栈结构,先进后出。
函数调用
function add() {
return 1 + 1
}
add()
add()函数调用时,会产生add函数的执行上下文,此时也存在全局执行上下文,当有多个函数执行时,就会存在多个执行上下文,那么,调用栈就是用栈结构用来管理这些的。
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)
分析这段代码来观察调用栈的变化情况。
- 1.创建全局上下文,压入栈底。
- 2.addAll 函数开始执行。
- 3.JavaScript引擎编译addAll函数,并为addAll 创建执行上下文,并将该函数的执行上下文,压入栈中,
- 4.addAll函数又调用了 add 函数,同样为 add创建执行上下文,并将该函数的执行赏析问,压入栈中。
- 5.add函数执行完毕,该函数的执行上下文从栈顶弹出,
- 6.addAll函数执行完毕,该函数的执行上下文从栈顶弹出,
- 7.此时栈中只剩下全局执行上下文,整个JavaScript流程执行完毕。
调用栈就是一种管理机制
调用栈是 JavaScript 引擎追踪函数执行的一个机制,当一次有多个函数被调用时,通过调用栈就能够追踪到哪个函数正在被执行以及各函数之间的调用关系。
怎么利用调用栈
- 1.浏览器中断点调试
- 2.在代码中 假如console.trace() 来追踪当前调用栈
function add() {
console.trace()
return 1 + 1
}
add()
栈溢出
调用栈也是又大小的,当调用栈中的执行上下文过多时,JavaScript引擎就会报错,这种就做栈溢出。 尤其实在写递归的时候,很容易出现栈溢出的情况。
怎样解决栈溢出
- 1.尾递归
- 2.不入栈
ref: 阮一峰教程