Skip to content

在 JavaScript 中,执行上下文(Execution Context)是代码在运行时的环境,决定了变量或函数的访问权限以及它们的行为。每当 JavaScript 代码执行一段代码块时,都会创建一个新的执行上下文。

执行上下文的类型

JavaScript 中有三种执行上下文:

  1. 全局执行上下文:这是默认的、最基础的执行上下文。浏览器中的全局上下文就是 window 对象,而在 Node.js 中则是 global 对象。在全局执行上下文中定义的变量和函数都可以在整个程序中访问。

  2. 函数执行上下文:每次调用一个函数时,都会为该函数创建一个新的执行上下文。每个函数都有自己的执行上下文,且相互独立。

  3. Eval 执行上下文:当代码在 eval() 函数中执行时,会创建一个独立的执行上下文(不常用)。

执行上下文的生命周期

每个执行上下文都会经历三个阶段:

  1. 创建阶段

    • 变量对象(Variable Object,VO):在创建阶段,变量、函数声明和函数的形参都会被存储在变量对象中。在函数执行上下文中,变量对象通常称为“活动对象”(Activation Object,AO)。
    • 词法环境(Lexical Environment):用来存储函数中的变量和外部变量的引用,包括作用域链的维护。
    • This 绑定:确定在这个执行上下文中的 this 值。对于全局上下文,this 通常指向 window(或 global)。
  2. 执行阶段

    • 在这一阶段,代码会按照顺序执行,变量会被赋值,函数会被调用。
  3. 销毁阶段

    • 当代码执行完毕,执行上下文会被销毁,内存资源会被释放。

执行栈(调用栈)

JavaScript 是单线程的,使用执行栈(调用栈)来管理多个执行上下文。执行栈是一个后进先出(LIFO)的数据结构,当新的执行上下文被创建时,它会被压入执行栈的顶部。当上下文执行结束时,它会被从栈顶弹出。

  • 全局执行上下文永远位于栈底。
  • 每当调用一个函数时,函数的执行上下文会被压入栈顶。
  • 当函数执行完毕,它的执行上下文会从栈中弹出,控制权返回到上一个上下文。

作用域链和闭包

每个执行上下文都有一个与之关联的作用域链,用来保证当前执行代码对变量的有序访问。当在一个函数中定义函数时,内部函数会记住外部函数中的变量,即闭包的形成。


这些概念在理解 JavaScript 的执行流程、作用域、闭包、以及事件循环等方面非常重要。