哪些情况下代码才算是“⼀段”代码
1. 当JavaScript执⾏全局代码的时候,会编译全局代码并创建全局执⾏上下⽂,⽽且在整个⻚⾯的⽣存周期 内,全局执⾏上下⽂只有⼀份。
2. 当调⽤⼀个函数的时候,函数体内的代码会被编译,并创建函数执⾏上下⽂,⼀般情况下,函数执⾏结 束之后,创建的函数执⾏上下⽂会被销毁。
3. 当使⽤eval函数的时候,eval的代码也会被编译,并创建执⾏上下⽂。

那为什么会出现这种错误呢?这就涉及到了调⽤栈的内容
调⽤栈就是⽤来管理函数调⽤关系的⼀种数据结构
什么是函数调⽤
var a = 2
function add(){
var b = 10
return a+b
}
add()
- ⾸先,从全局执⾏上下⽂中,取出add函数代码。
- 其次,对add函数的这段代码进⾏编译,并创建该函数的执⾏上下⽂和可执⾏代码。
- 最后,执⾏代码,输出结果
当执⾏到add函数的时候,我们就有了两个执⾏上下⽂了⸺全局执⾏上下⽂和add函数的执⾏上 下⽂。
也就是说在执⾏JavaScript时,可能会存在多个执⾏上下⽂,那么JavaScript引擎是如何管理这些执⾏上下 ⽂的呢?
答案是通过⼀种叫栈的数据结构来管理的
什么是栈
栈中的元素满⾜后进先出的特点
JavaScript引擎正是利⽤栈的这种结构来管理执⾏上下⽂的。
通常把这种⽤来管理执⾏上下⽂的栈称为执⾏上下⽂栈,⼜称调⽤栈。
调⽤栈是JavaScript引擎追踪函数执⾏的⼀个机制
栈溢出(Stack Overflow)
调⽤栈是有⼤⼩的,当⼊栈的执⾏上下⽂超过⼀定数⽬,JavaScript引擎就会报错,我们把这种错误叫做栈溢出。
特别是在你写递归代码的时候,就很容易出现栈溢出的情况。
修改以下代码使其不会栈溢出
function runStack (n) {
if (n === 0) return 100;
return runStack( n- 2);
}
runStack(50000)
尾递归解决
function runStack (n, result=100) {
if (n === 0) return result;
return runStack( n- 2, result);
}
runStack(50000, 100)
或者循环解决
function runStack (n) {
while(true)
{
if (n === 0) return 100;
else if (n==1) return 100;
else {
n=n-2
}
}
}