全局执行上下文在js引擎启动时创建,函数执行上下文在每次调用时创建;前者作用域链仅含全局环境,后者在创建阶段就基于定义位置固定作用域链;var和function声明被提升并初始化,let/const仅注册于词法环境而处于暂时性死区。

JavaScript中,全局执行上下文和函数执行上下文的生成过程都遵循“创建阶段 + 执行阶段”两步机制,但触发时机、作用域链构成和变量提升细节存在关键差异。
全局执行上下文的生成过程
当JS引擎启动(如页面加载、Node.js运行脚本),会自动创建唯一的全局执行上下文。它分为两个阶段:
- 创建阶段:初始化全局对象(浏览器中是window,Node中是global)、this指向该全局对象;扫描所有var声明,将其设为undefined(变量提升);处理function声明,将函数名作为属性挂载到全局对象,并赋值为函数体(函数提升);let/const声明被记录在词法环境但不初始化,进入“暂时性死区”。
- 执行阶段:按代码顺序逐行执行。遇到var赋值则更新值;遇到let/const赋值才完成初始化;执行函数调用会暂停当前上下文,压入新的函数执行上下文。
函数执行上下文的生成过程
每次函数被调用时,引擎动态创建一个独立的函数执行上下文,生命周期仅限于该次调用。
- 创建阶段:建立自己的词法环境(含参数、let/const、内部function声明)和变量环境(主要处理var);参数对象(arguments)和形参被绑定并初始化;this值根据调用方式确定(默认绑定、隐式绑定、显式绑定或箭头函数继承外层);作用域链由自身词法环境 + 外部词法环境(即定义时的父级作用域)组成,不是调用时的父级。
- 执行阶段:执行函数体内的语句;遇到嵌套函数调用,重复创建新上下文并入栈;函数返回后,该上下文被销毁(若无闭包引用,内存可被回收)。
关键区别与常见误区
理解二者差异有助于排查变量访问、this指向和闭包问题:
- 全局上下文只创建一次,函数上下文每次调用都新建——这意味着每次调用都有独立的参数、let变量和this绑定。
- 作用域链构建时机不同:函数的作用域链在创建阶段就固定(基于函数定义位置),而非调用位置;全局上下文的作用域链只有全局词法环境本身。
- this绑定规则在函数创建阶段不决定,而是在执行阶段根据调用方式实时计算;全局上下文中this始终指向全局对象(非严格模式)或undefined(严格模式)。
- 变量提升仅对var和function声明生效;let/const虽被“提升”到词法环境,但不可访问直到初始化语句执行——这是TDZ的本质。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











