在 JavaScript 中,执行上下文(Execution Context,EC)是指在代码执行过程中,JavaScript 引擎创建的一个抽象概念,用于描述代码的执行环境。每当 JavaScript 引擎执行一段代码时,都会创建一个新的执行上下文,并将其压入执行上下文栈(Execution Context Stack,ECS)中。当代码执行完毕后,执行上下文会从栈中弹出,并被销毁。
每个执行上下文都包含了三个重要的组成部分:
- 变量环境(Variable Environment,VE):用于存储变量和函数::声明::。
- 词法环境(Lexical Environment,LE):用于存储变量和函数的::作用域信息::。
- this 值:用于存储当前函数的::执行上下文所关联的 this 对象::。
下面是一个例子,用于说明执行上下文的概念:
var a = 1;
function foo() {
var b = 2;
console.log(a + b);
}
foo();
在执行上面的代码时,JavaScript 引擎会依次创建以下三个执行上下文:
- 全局执行上下文:在代码开始执行时创建,用于描述全局作用域。
- 变量环境:包含全局变量
a和函数foo的声明。 - 词法环境:与变量环境相同。
- this 值:全局对象(在浏览器中为
window对象)。
- 变量环境:包含全局变量
- 函数
foo的执行上下文:在调用函数foo时创建,用于描述函数foo的作用域。- 变量环境:包含变量
b的声明。 - 词法环境:与变量环境相同。
- this 值:全局对象(在浏览器中为
window对象)。
- 变量环境:包含变量
console.log的执行上下文:在执行console.log语句时创建,用于描述console.log的作用域。- 变量环境:无变量声明。
- 词法环境:与变量环境相同。
- this 值:全局对象(在浏览器中为
window对象)。
需要注意的是,每个执行上下文都有自己的变量环境和词法环境。在访问变量或者函数时,JavaScript 引擎会
- 先在当前执行上下文的变量环境中查找对应的变量或函数
- 如果找不到,则会继续在当前执行上下文的词法环境中查找。
- 如果还是找不到,则会继续向外层执行上下文中查找,直到找到为止。
a = 1
function foo() {
a = 2
console.log(a)
}
a = 3
foo()
console.log(a)
上面代码a的赋值顺序分别是什么?最终输出结果分别是多少?
在 JavaScript 中,代码的执行顺序是从上到下依次执行的。因此,在上面的代码中,赋值语句的顺序是按照代码的书写顺序来执行的。
具体来说,代码的执行顺序如下:
- 执行
a = 1,将全局变量a的值赋为 1。 - 执行
function foo() { ... },定义函数foo。 - 执行
a = 3,将全局变量a的值修改为 3。 - 执行
foo(),调用函数foo。 - 执行函数
foo内部的a = 2,将全局变量a的值修改为 2。 - 执行函数
foo内部的console.log(a),输出全局变量a的值,即 2。 - 执行全局作用域中的
console.log(a),输出全局变量a的值,即 2。
因此最终输出结果是:2 2