JavaScript执行上下文是代码运行的环境容器,决定变量、函数、this的查找与求值;分全局、函数、eval三种类型,生命周期含创建(处理声明与this)和执行(赋值与运算)两阶段,由执行上下文栈调度。

JavaScript执行上下文(Execution Context)是代码运行时的“环境容器”,它决定了变量、函数、this等如何被查找和求值。理解它,就等于看懂了JS代码“从哪开始执行、变量在哪能用、为什么有些变量还没定义就能调用”这些关键问题的底层逻辑。
执行上下文的类型和创建时机
JS中主要有三种执行上下文:
-
全局执行上下文:脚本启动时自动创建,一个JS文件(或模块)对应一个。它确定了全局对象(浏览器中是
window)、this指向、以及最外层的变量和函数声明。 -
函数执行上下文:每次函数被调用时创建,独立于调用位置。每个调用都有自己的上下文,保存该次调用的参数、局部变量、作用域链和
this值。 -
Eval执行上下文(已不推荐使用):在
eval()中执行字符串代码时创建,行为类似函数上下文但有安全与性能风险,现代开发中基本不用。
执行上下文的生命周期:创建阶段 vs 执行阶段
每个上下文分两步构建,这个过程直接影响你看到的“变量提升”现象:
-
创建阶段(进入上下文时立即发生):
• 创建词法环境(Lexical Environment),初始化let/const为uninitialized状态;
• 创建变量环境(Variable Environment),将var声明设为undefined,函数声明直接赋值为函数体;
• 确定this值(全局中是全局对象,普通函数调用中也是全局对象,箭头函数则继承外层this)。 -
执行阶段(按代码顺序逐行执行):
• 为var赋实际值;
• 对let/const执行赋值(若在声明前访问,会报ReferenceError,即暂时性死区TDZ);
• 执行函数调用、表达式计算等。
执行上下文栈(Call Stack)如何调度代码
JS是单线程的,靠执行上下文栈管理当前正在运行和待运行的上下文:
立即学习“Java免费学习笔记(深入)”;
- 全局上下文最先入栈;
- 每次函数调用,新函数上下文被压入栈顶;
- 函数返回后,其上下文被弹出,控制权交还给栈下一个上下文;
- 栈为空时,JS引擎空闲等待新任务(如事件、定时器)。
例如:foo()调用bar(),再调用baz(),栈从底到顶就是:[全局 → foo → bar → baz]。任一函数出错,错误堆栈正是这个顺序的反向体现。
执行上下文怎样影响日常编码
很多常见行为都由上下文机制决定:
-
变量提升只对
var和函数声明生效:因为它们在创建阶段就被处理;let/const虽也进入词法环境,但处于TDZ,不能访问。 - 闭包的本质是词法环境的保留:内层函数执行完毕后,若其词法环境仍被外层引用(比如返回了内部函数),该环境不会被销毁,其中的变量持续可用。
-
this不是由函数定义位置决定,而是由调用方式决定:因为this是在函数上下文创建阶段绑定的,取决于谁调用、怎么调用(obj.fn()、fn.call(obj)、箭头函数等规则不同)。 - 立即执行函数(IIFE)能隔离变量,本质是制造独立的函数执行上下文,避免污染全局。










