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

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变量初始化为undefined,function声明完成提升;this值根据调用方式确定(如普通调用为undefined(严格模式)或全局对象,new调用指向新实例,call/apply由传入值决定)。 - 执行阶段:执行函数体内部语句,访问自身词法环境中的变量,通过作用域链向上查找外层变量。
- 函数上下文是栈结构(执行上下文栈,ECStack),调用时入栈,返回时出栈;递归调用会生成多个嵌套的函数上下文。
关键差异与常见误区
理解两者差异有助于避开典型陷阱:
立即学习“Java免费学习笔记(深入)”;
-
this绑定时机不同:全局上下文中
this在创建阶段就确定(指向全局对象/undefined);函数上下文中this值在调用时才确定,与定义位置无关,只取决于调用语法。 -
词法环境链起点不同:全局上下文的外部环境引用为
null;函数上下文的外部环境引用指向其定义时的外层词法环境(即闭包实现的基础)。 -
变量提升范围不同:“提升”仅发生在创建阶段,且只针对
var和function声明;let/const不提升,只是声明被记录,访问前报错(TDZ)。 - 箭头函数没有自己的
this、arguments、super或new.target,它直接从外层函数上下文继承这些值,因此不生成完整的函数执行上下文(无独立this绑定逻辑)。
简单验证方式
可通过调试工具或日志辅助观察上下文行为:
- 在Chrome DevTools中打断点,查看“Scope”面板,能清晰看到
Global、Closure、Function等作用域层级。 - 用
console.log(this)在不同位置输出,对比全局、普通函数、对象方法、箭头函数中的结果。 - 尝试在
let声明前访问变量,验证TDZ报错,而var则得undefined,体现创建阶段差异。








