JavaScript中全局执行上下文与函数上下文生成过程

1次阅读

全局执行上下文在脚本加载时创建,初始化 var/function 并绑定全局 this;函数执行上下文在每次调用时创建,基于词法作用域构建环境,this 值由调用方式决定,且具栈式生命周期。

JavaScript 中全局执行上下文与函数上下文生成过程

JavaScript 中,全局执行上下文和函数执行上下文的生成过程,本质是引擎在代码运行前为作用域、变量、this 等做初始化准备的阶段,核心区别在于触发时机、this 绑定、词法环境结构和变量提升行为。

全局执行上下文的生成过程

当脚本首次加载并开始执行时,JS 引擎自动创建唯一的全局执行上下文(Global Execution Context),它是整个程序的根上下文:

  • 创建阶段 :引擎扫描全局代码,声明所有var 变量(初始化为 undefined)和function 声明(完整函数对象被提升并赋值);let/const虽被声明但处于“暂时性死区”,不初始化;全局对象(如浏览器中的 window 或 Node.js 中的 global)被设为this 值。
  • 执行阶段 :按顺序执行语句,为var 赋值,初始化let/const,执行函数调用——每次调用都会触发新函数上下文的创建。
  • 全局上下文只有 1 个,生命周期贯穿整个脚本运行,直到页面卸载或进程退出。

函数执行上下文的生成过程

每当函数被调用(包括箭头函数、构造器调用等),引擎立即为其创建一个独立的函数执行上下文:

  • 创建阶段 :基于函数定义时的词法作用域,构建自己的词法环境(LexicalEnvironment)和变量环境(VariableEnvironment);形参和arguments 对象被初始化;var变量初始化为 undefinedfunction 声明完成提升;this值根据调用方式确定(如普通调用为 undefined(严格模式)或全局对象,new 调用指向新实例,call/apply由传入值决定)。
  • 执行阶段:执行函数体内部语句,访问自身词法环境中的变量,通过作用域链向上查找外层变量。
  • 函数上下文是栈结构(执行上下文栈,ECStack),调用时入栈,返回时出栈;递归调用会生成多个嵌套的函数上下文。

关键差异与常见误区

理解两者差异有助于避开典型陷阱:

立即学习Java 免费学习笔记(深入)”;

  • this 绑定时机不同 :全局上下文中this 在创建阶段就确定(指向全局对象 /undefined);函数上下文中 this 值在调用时才确定,与定义位置无关,只取决于调用语法。
  • 词法环境链起点不同:全局上下文的外部环境引用为null;函数上下文的外部环境引用指向其定义时的外层词法环境(即闭包实现的基础)。
  • 变量提升范围不同 :“提升”仅发生在创建阶段,且只针对varfunction声明;let/const不提升,只是声明被记录,访问前报错(TDZ)。
  • 箭头函数没有自己的 thisargumentssupernew.target,它直接从外层函数上下文继承这些值,因此不生成完整的函数执行上下文(无独立 this 绑定逻辑)。

简单验证方式

可通过调试工具或日志辅助观察上下文行为:

  • 在 Chrome DevTools 中打断点,查看“Scope”面板,能清晰看到 GlobalClosureFunction 等作用域层级。
  • console.log(this) 在不同位置输出,对比全局、普通函数、对象方法、箭头函数中的结果。
  • 尝试在 let 声明前访问变量,验证 TDZ 报错,而 var 则得undefined,体现创建阶段差异。
text=ZqhQzanResources