javascript中执行上下文和执行栈是什么?

2024-07-20 20:28:06 143
在JavaScript中,**执行上下文(Execution Context)**和**执行栈(Execution Stack)**是理解代码执行机制的关键概念。它们帮助解释了变量和函数的作用域、函数调用的顺序,以及异步操作的处理方式。

执行上下文(Execution Context)

执行上下文是 JavaScript 代码执行时的环境。每当 JavaScript 代码执行一段可执行代码(如全局代码、函数代码或 eval 代码)时,都会创建一个对应的执行上下文。

执行上下文类型

  1. 全局执行上下文

    • 默认创建的执行上下文,包含全局对象(如 window 对象)和 this
    • 任何不在函数内部的代码都在全局执行上下文中执行。
  2. 函数执行上下文

    • 每次调用函数时都会创建一个新的函数执行上下文。
    • 每个函数都有自己的执行上下文,包括函数内部的变量、参数、以及 this
  3. eval 执行上下文

    • eval 函数创建(在严格模式下不推荐使用)。

执行上下文的生命周期

执行上下文的生命周期分为三个阶段:

  1. 创建阶段

    • 创建变量对象(Variable Object,VO):存储函数的参数、内部变量和函数声明。
    • 建立作用域链(Scope Chain):用于标识符解析。
    • 确定 this 绑定:决定 this 的指向。
  2. 执行阶段

    • 执行代码,分配变量值,执行函数,处理表达式。
  3. 销毁阶段

    • 执行上下文在函数执行完毕后会被销毁,释放内存。

执行栈(Execution Stack)

执行栈,也称为调用栈,是一个后进先出(LIFO,Last In First Out)结构,用于存储在代码执行期间创建的所有执行上下文。每当函数调用时,会创建一个新的执行上下文并将其推入执行栈的顶部。

执行栈的工作机制

  1. 全局执行上下文入栈

    • 当 JavaScript 引擎首次运行代码时,会创建一个全局执行上下文并将其压入执行栈。
  2. 函数调用

    • 每次调用函数时,都会创建一个新的函数执行上下文,并将其压入执行栈的顶部。
    • 函数执行完毕后,相应的函数执行上下文会从执行栈中弹出。
  3. 栈顶执行

    • 当前正在执行的代码始终位于执行栈的顶部。
    • JavaScript 引擎执行栈顶的上下文,执行完毕后从栈中弹出。

示例

function first() {
  second();
  console.log('first');
}

function second() {
  third();
  console.log('second');
}

function third() {
  console.log('third');
}

first();

执行上述代码的过程:

  1. 全局执行上下文入栈
  2. 调用 first 函数
    • 创建 first 函数执行上下文并压入栈顶。
  3. 调用 second 函数
    • 创建 second 函数执行上下文并压入栈顶。
  4. 调用 third 函数
    • 创建 third 函数执行上下文并压入栈顶。
    • third 函数执行完毕后,其执行上下文从栈中弹出。
  5. 继续执行 second 函数
    • 输出 secondsecond 函数执行完毕后,其执行上下文从栈中弹出。
  6. 继续执行 first 函数
    • 输出 firstfirst 函数执行完毕后,其执行上下文从栈中弹出。
  7. 全局执行上下文继续执行

最终输出:

third
second
first

总结

  • 执行上下文 是代码执行时的环境,每段可执行代码(全局、函数、eval)都有自己的执行上下文。
  • 执行栈 是一个存储执行上下文的后进先出结构,管理代码执行的顺序。
  • 理解执行上下文和执行栈,有助于更好地掌握 JavaScript 的函数调用、作用域和异步操作。