执行上下文

75 阅读2分钟

概念

  • 是JS代码执行时的环境,包含了变量,作用域链,this等信息
  • ES6后的执行上下文结构更复杂,区分了变量环境和词法环境

类型

  1. 全局执行上下文
    • 首次代码执行时创建,全局唯一,生命周期与程序一致
  2. 函数执行上下文
    • 每次函数调用时创建,函数执行完毕后销毁
  3. Eval执行上下文
    • eval函数内部的代码

组成部分

  1. 变量对象
  2. 作用域链
  3. this指针

生命周期

1. 创建阶段(ES6后执行上下文结构)
  • 变量环境
    • 处理var声明和函数声明(函数提升)。
    • 变量初始化为undefined,函数声明完全提升。
    console.log(a)  // undefined
    console.log(foo) // Function
    var a = 1;
    function foo() {};
    
  • 词法环境
    • 处理let const 声明和块级作用域。
    • 变量未初始化(处于暂时性死区,访问报错)。
    console.log(a) // 报错
    let a = 1;
    if (true) { const b = 2; };
    console.log(b) // 报错 Uncaught ReferenceError: b is not defined
    
  • 作用域链
    • 由词法环境的外部引用形成,决定变量的查找路径
    • 函数在定义时确定作用域链(词法作用域)。
  • this绑定
    • 全局上下文中,this指向全局对象
    • 函数上下问中,this由调用方式决定
      • 箭头函数的没有自己的this,会自动继承外层this
2. 执行阶段
  • 逐行执行代码,完成变量赋值、函数调用等操作。
  • 处理异步任务(如回调、Promise)时,通过事件循环管理执行顺序。
3. 回收阶段
  • 执行完毕后,若不被闭包引用,内存会被垃圾回收机制释放。

执行栈

  • 执行上下文按调用顺序压入栈中,栈顶的上下文处于执行状态。
function a() { b() }
function b() { c() }
function c() {}

a() // 执行栈顺序: window -> a -> b -> c

关键特性

  1. 变量提升与暂时性死区
  • var变量和函数声明在创建阶段提升。
  • let const存在暂时性死区,声明前访问会报错。
  1. 闭包形成
  • 内部函数保留外层作用域的引用,导致外层上下文变量无法释放。
function outer() {
    const x = 1
    return function inner() {
        console.log(x)
    }
}
const fn = outer() // outer的变量x被闭包保留
  1. 块级作用域(ES6)
  • {}let/const声明的变量仅存在于块中。
    if (true) {
      let a = 1; // 仅在此块内有效
    }
    

总结

  • 执行上下文是JS执行的基础机制。