一、执行上下文(Execution Context)
1.1 什么是执行上下文
- 执行上下文(
Execution Context, EC
)可以理解为 当前代码的执行环境,它会形成一个作用域。
1.2 堆栈
- 活动的执行上下文组在逻辑上组成了一个堆栈。
- 堆栈底部 永远是 全局上下文(
Global Context
)。- 堆栈顶部 是 当前(活动的)执行上下文。
- 堆栈在
EC
类型进入和退出上下文时被修改 — 推入或弹出。- 我们可以将执行上下文的堆栈看作一个数组:
ECStack = []
。- 只要执行流进入
function
,这个function
就会被压入堆栈内。
1.3 EC 分类
EC
分为两类:
- 1.全局执行上下文(全局环境):
Javascript
代码运行时会先进入该环境。- 全局执行环境直到应用程序退出,保存在其中的所有变量和函数定义才会被销毁。
- 全局代码不包括任何
function
体内的代码。
- 堆栈:
- 2.函数执行上下文(函数环境):
- 当函数被调用时,会进入当前函数中执行代码。
- 执行环境中的所有代码执行完毕后,改环境被销毁,保存在其中的所有变量和函数定义也会被销毁。
- 堆栈:
1.4 EC的生命周期
EC
的生命周期如下:
1.5 EC 实例1
- 代码如下:
var color = 'blue';
function changeColor() {
var anotherColor = 'red';
function swapColors() {
var tempColor = anotherColor;
anotherColor = color;
color = tempColor;
}
swapColors();
}
changeColor();
- 数组理解:
var ECStack = [];
ECStack[0] = changeColor;
ECStack[1] = swapColor;
ECStack[2] = globalContext;
// 实际上就是:
var ECStack = [changeColor, swapColor, globalContext];
- 图示理解:
1.6 EC 实例2
- 代码如下:
function f1 () {
var n = 100;
function f2 () {
console.log(n);
}
return f2;
}
var result = f1();
result(); // 100
- 图示理解:
- 可从图上看到
f1
出栈后result
(即:f2
)才入栈。- 原因:因为
f1
中的函数f2
在f1
的可执行代码中并没有被调用执行,因此,执行f1
时,f2
不会创建新的上下文, 直到result
执行时,才创建其上下文。
二、总结
- 只有 栈顶 的上下文处于执行阶段,其他上下文需等待执行。
- 全局上下文只有一个,它只有在浏览器关闭时出栈。
- 函数的执行上下文的个数没有限制。
- 只要有函数被调用,就会有新的执行上下文被创建,即使调用自身的函数也是如此。