执行上下文生命周期分为创建、执行、回收三阶段:创建阶段初始化变量对象、作用域链和this;执行阶段赋值并运行代码;回收阶段出栈并清理内存。

JavaScript 执行上下文(Execution Context,简称 EC)不是运行时的“快照”,而是一套严格分阶段、可追溯的环境初始化与销毁机制。它的生命周期直接决定变量能否访问、this 指向是否正确、函数为何能提前调用——理解它,等于看清 JS 代码真正“怎么动起来”的第一步。
执行上下文的三种类型
JS 引擎只在三类场景中创建执行上下文:
-
全局执行上下文:脚本加载后立即创建,且仅有一个。浏览器中绑定到
window,Node 中绑定到global;this指向该全局对象。 -
函数执行上下文:每次函数被调用时新建一个,哪怕重复调用同一函数(如
foo()调用两次 → 创建两个独立 EC)。 -
Eval 执行上下文:仅当使用
eval()且传入字符串代码时触发,日常开发极少涉及,可暂不深究。
创建阶段:代码还没执行,环境已就位
这个阶段发生在函数调用发生、但第一行函数体代码尚未运行之前。JS 引擎同步完成四件事:
-
生成变量对象(VO):
• 初始化
arguments对象(含实参值和callee等属性); • 提升所有function声明(函数名→内存地址引用,同名函数后声明覆盖前声明); • 提升所有var声明(变量名→undefined),但跳过已存在的函数名属性; •let/const声明不提升,进入“暂时性死区”(TDZ),访问即报错。 -
建立作用域链:将当前函数的
[[Scope]](词法嵌套时捕获的外层 VO/AO 链表)复制过来,并把当前 VO 添加到链首。 -
确定
this值:根据调用方式静态绑定—— • 普通调用(fn()):非严格模式为全局对象,严格模式为undefined; • 方法调用(obj.fn()):this指向obj; • 构造调用(new Fn()):this是新创建的实例; • 显式绑定(call/apply/bind):以传入对象为准。
执行阶段:逐行跑代码,填充真实值
创建阶段完成后,引擎开始按顺序执行函数体内的语句。此阶段主要做三类事:
- 为
var变量赋实际值(如var a = 10→ VO 中a从undefined变为10); - 执行函数调用、表达式求值、对象操作等全部可运行逻辑;
- 遇到
let/const声明时,退出 TDZ 并初始化(const必须立即赋值)。
回收阶段:上下文出栈,内存待清理
函数执行完毕(包括遇到 return 或自然结束),对应执行上下文从执行上下文栈(ECS)顶部弹出。此时:
- VO/AO 不再可访问,其中变量若无其他引用,将被垃圾回收器标记为可回收;
- 作用域链断开,外层无法再通过闭包访问该 EC 的局部变量(除非有闭包引用保留);
- 栈中仅剩全局 EC,直到整个程序结束才被清空。
执行上下文不是黑箱,它是 JS 运行时最基础的调度单元。每个函数调用都在栈上留下清晰痕迹,每个变量提升都有明确依据。搞懂它,变量为什么未定义就报错、this 为何突然变 undefined、闭包为何能记住旧值——全都有解。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











