1.执行上下文是什么?
从定义上看:执行上下文是“执行代码的环境”。我们可以从一下层面理解它:
- 执行上下文的分类
- 执行上下文的生命周期
- 执行上下文的创建和组成
2.执行上下文的分类
- 全局上下文——全局代码所处的环境,不在函数中的代码都在全局执行环境中。
- 函数上下文——在函数调用时创建的上下文。
- Eval执行上下文(不用管)
3.执行上下文的生命周期
- 创建阶段——执行上下文的初始化状态,此时一行代码都没执行,只做了一些准备工作。
- 执行阶段——逐行执行脚本里的代码。
4.执行上下文的创建和组成
4-1 全局上下文的创建和组成
当 js 脚本跑起来之后,第一个被创建的执行上下文就是全局上下文,包含两个东西:
- 全局对象(浏览器是window,Node环境是Global)
- this变量。这里的this,指向的还是全局变量。
var name = 'xiuyan'
var tel = '123456'
function getMe() {
return {
name: name,
tel: tel
}
}
创建阶段
执行阶段
4-2 在上下文的角度看“变量提升”
// 没有报错,而是输出 undefined
console.log(name)
var name = 'xiuyan'
所谓的“变量提升”,只不过是变量的创建过程(在上下文创建阶段完成)和真实赋值(在上下文的执行阶段完成)的不同步带来的错觉。
4-3 函数上下文的创建和组成
- 创建的时机:在函数被调用时创建。
- 创建的频率:其创建的次数由函数调用的次数决定。
- 创建的内容:创建出一个参数对象(arguments),this指向取决于函数是如何被调用。
5.调用栈
- 在 js 代码的执行过程中,引擎会为我们创建“执行上下文栈”(调用栈)
- 上下文的建立和销毁,对应“入栈”和“出栈‘
function testA() {
console.log('执行第一个测试函数的逻辑');
testB();
console.log('再次执行第一个测试函数的逻辑');
}
function testB() {
console.log('执行第二个测试函数的逻辑');
}
testA();
- 执行之初,全局上下文创建
- 执行到testA调用处,testA对应的函数上下文创建
- 执行到testB调用处,testB对应的函数上下文创建
- testB 执行完毕,对应上下文出栈,剩下 testA 和全局上下文。
- testB 执行完毕,对应上下文出栈,剩下 全局上下文。