返回

JavaScript如何在栈(ECS)内运行?——运行上下文(EC)

前端

在计算机科学中,栈(执行上下文栈)是一种数据结构,它遵循后进先出的原则存储数据。它通常用于存储函数调用过程中局部变量和参数的值。JavaScript 作为一门基于栈的语言,在运行过程中也需要使用栈来管理执行上下文(EC)。

执行上下文

执行上下文(EC)是一个包含当前正在执行代码的信息的特殊对象。它包含以下信息:

  • 变量环境(VE): 存储当前作用域内所有变量的值。
  • 作用域链: 包含所有父级作用域的引用,允许访问外层作用域的变量。
  • this :指向当前执行上下文中的 this 对象。

JavaScript 在栈中的运行

JavaScript 代码在执行时,会被解释器转换为字节码,然后由执行引擎执行。执行引擎将创建一个执行上下文(EC)并将其压入栈中。EC 包含代码执行所需的所有信息,包括变量环境、作用域链和 this 对象。

当函数被调用时,一个新的 EC 将被创建并压入栈中。这个新的 EC 继承了父级作用域的变量环境和作用域链,但是拥有自己的局部变量环境和 this 对象。

当函数返回时,其 EC 将被从栈中弹出,并恢复到调用函数的 EC。这个过程一直持续到所有函数调用完成,并且栈中只保留全局执行上下文(GEC)。

作用域和栈

作用域是一个包含所有可访问变量的区域。在 JavaScript 中,作用域是词法作用域,这意味着它由代码在源代码中的位置决定。

作用域与栈紧密相关。在代码执行时,栈中的当前 EC 决定了当前的作用域。当函数被调用时,一个新的 EC 被压入栈中,并创建了一个新的作用域。当函数返回时,栈中的 EC 被弹出,作用域也随之改变。

通过这种机制,JavaScript 能够管理多个作用域,并允许在不同作用域之间访问变量。

示例

考虑以下代码:

function outer() {
  let x = 10;

  function inner() {
    console.log(x); // 10
  }

  inner();
}

outer();

在这个示例中,outer() 函数创建了一个新的执行上下文,并将其压入栈中。这个 EC 包含一个变量环境,其中存储了变量 x

inner() 函数被调用时,一个新的 EC 被创建并压入栈中。这个新的 EC 继承了 outer() 函数的变量环境和作用域链,因此可以访问变量 x

inner() 函数返回时,其 EC 被从栈中弹出,并恢复到 outer() 函数的 EC。

结论

栈是 JavaScript 执行环境的核心组件。它允许引擎管理执行上下文,包括变量环境、作用域链和 this 对象。通过了解 JavaScript 在栈中如何运行,我们可以更好地理解 JavaScript 的执行机制和作用域规则。