JS 执行上下文

102 阅读3分钟

image.png

在 JavaScript 中,执行上下文(Execution Context,EC)是指在代码执行过程中,JavaScript 引擎创建的一个抽象概念,用于描述代码的执行环境。每当 JavaScript 引擎执行一段代码时,都会创建一个新的执行上下文,并将其压入执行上下文栈(Execution Context Stack,ECS)中。当代码执行完毕后,执行上下文会从栈中弹出,并被销毁。

每个执行上下文都包含了三个重要的组成部分:

  1. 变量环境(Variable Environment,VE):用于存储变量和函数::声明::。
  2. 词法环境(Lexical Environment,LE):用于存储变量和函数的::作用域信息::。
  3. this 值:用于存储当前函数的::执行上下文所关联的 this 对象::。

下面是一个例子,用于说明执行上下文的概念:

var a = 1;

function foo() {
  var b = 2;
  console.log(a + b);
}

foo();

在执行上面的代码时,JavaScript 引擎会依次创建以下三个执行上下文:

  1. 全局执行上下文:在代码开始执行时创建,用于描述全局作用域。
    • 变量环境:包含全局变量 a 和函数 foo 的声明。
    • 词法环境:与变量环境相同。
    • this 值:全局对象(在浏览器中为 window 对象)。
  2. 函数 foo 的执行上下文:在调用函数 foo 时创建,用于描述函数 foo 的作用域。
    • 变量环境:包含变量 b 的声明。
    • 词法环境:与变量环境相同。
    • this 值:全局对象(在浏览器中为 window 对象)。
  3. console.log 的执行上下文:在执行 console.log 语句时创建,用于描述 console.log 的作用域。
    • 变量环境:无变量声明。
    • 词法环境:与变量环境相同。
    • this 值:全局对象(在浏览器中为 window 对象)。

需要注意的是,每个执行上下文都有自己的变量环境和词法环境。在访问变量或者函数时,JavaScript 引擎会

  1. 先在当前执行上下文的变量环境中查找对应的变量或函数
  2. 如果找不到,则会继续在当前执行上下文的词法环境中查找。
  3. 如果还是找不到,则会继续向外层执行上下文中查找,直到找到为止。

a = 1
function foo() {
  a = 2
  console.log(a)
}
a = 3
foo()
console.log(a)

上面代码a的赋值顺序分别是什么?最终输出结果分别是多少?

在 JavaScript 中,代码的执行顺序是从上到下依次执行的。因此,在上面的代码中,赋值语句的顺序是按照代码的书写顺序来执行的。

具体来说,代码的执行顺序如下:

  1. 执行 a = 1,将全局变量 a 的值赋为 1。
  2. 执行 function foo() { ... },定义函数 foo
  3. 执行 a = 3,将全局变量 a 的值修改为 3。
  4. 执行 foo(),调用函数 foo
  5. 执行函数 foo 内部的 a = 2,将全局变量 a 的值修改为 2。
  6. 执行函数 foo 内部的 console.log(a),输出全局变量 a 的值,即 2。
  7. 执行全局作用域中的 console.log(a),输出全局变量 a 的值,即 2。

因此最终输出结果是:2 2