理解执行栈 和执行上下文
执行上下文(执行上下文环境)
一句话简单概括:就是代码执行前的准备工作,也叫执行上下文环境。
运行javascript 代码时,当代码执行进入一个环境时,就会为当前环境创建一个执行上下文,他会在代码运行前做一些准备工作:创建变量(v o),改变this 指向,确定作用域链等。
javascript 中的执行环境
- 全局环境
- 函数环境
- eval 环境(已经不推荐使用)
那么与之对应的执行上下文也有三种:
-
全局执行上下文
-
函数执行上下文
-
eval 执行上下文
栈数据结构
遵循先进后出,后进先出的原则,或者LIFO(Last In First Out)规则。
最先出去的永远是栈顶的数据

执行栈
理解完栈,接着分析JavaScript 中如何通过栈来管理多个执行上下文。
程序执行进入一个执行环境时,他的上下文就会被创建,并被推入执行栈中(入栈),程序执行完成时,它的执行上下文就会被销毁,并从栈顶被推出(出栈),控制权交给下一个执行上下文。
因为javascript在执行代码时最先进入全局环境,所以处于最底部的永远是全局环境的执行上下文,而处于栈顶的则是当前正在执行函数的执行上下文。
var a=1;
var b= far
console.log(b)
console.log(far)
function far(){
var c=2
console.log(c)
console.log(a)
}
b()
--- 创建全局上下文环境
Vo阶段(Variable Object)
vo={
a:undefined,
b:function far,
far:function far
}
改变当前this指向;
确定当前作用域链
代码执行......
当代码运行到b()时:
---创建函数执行上下文
vo={
c:undefined
},
改变当前this指向;
确定当前作用域链;
代码执行.....
当代码执行到 console.log(a) 时,
从当前vo 中无法拿到a,于是向全局上下文环境中的vo去查找
下面来具体看一段具体的代码示例:
function foo(){
function bar(){
return 'I am boy'
}
return bar()
}
对应图解如下:

执行上下文的数量限制(堆栈溢出)
执行上下文可存在多个,虽然没有明确的数量限制,但是如果超出了栈分配的空间,就会造成堆栈溢出,常见于递归调用,没有终止条件造成死循环的场景