JavaScript在代码执行之前,引擎会先做一次编译处理,这个过程会创建执行上下文并把变量与函数声明提前安排好,这就是大家常说的变量提升。执行上下文决定了当前代码能够访问哪些标识符,以及这些标识符如何与作用域绑定。

什么是执行上下文
每当JavaScript开始运行一段代码,比如全局代码或一个函数体,就会生成一个执行上下文。它主要包含词法环境、变量环境以及this的指向。在上下文创建阶段,引擎会扫描代码中的声明,将函数声明和var声明的变量放入环境记录中。
创建阶段发生了什么
- 函数声明整体提升,可以直接调用
- var声明的变量提升并初始化为undefined
- let和const也会提升但处于暂时性死区,不能提前访问
变量提升的实际表现
看下面这段例子,我们在声明之前使用变量,并不会报错而是得到undefined:
// 变量提升示例
console.log(myName); // 输出 undefined
var myName = '张三';
console.log(myName); // 输出 张三
// 函数声明提升
sayHello(); // 输出 hello
function sayHello() {
console.log('hello');
}
上面代码中,var myName 的声明被提升到作用域顶部,但赋值留在原处,所以第一次打印是undefined。函数声明sayHello则被完整提升,因此可以提前调用。
let和const为什么不同
使用let或const声明的变量同样有提升动作,但引擎把它们放在暂时性死区中,在声明语句之前访问会直接抛错。
// let的暂时性死区 console.log(age); // 报错 ReferenceError let age = 18;
执行上下文与作用域绑定
每一个执行上下文都有自己的词法环境,里面保存了当前作用域的绑定关系。当代码在一个函数内查找变量时,会先搜当前函数的环境,找不到再沿外层环境向上查找,这就是作用域链。变量提升只在当前执行上下文内有效,不会跨上下文把变量提到其他函数里。
| 声明方式 | 是否提升 | 初始值 |
|---|---|---|
| var | 是 | undefined |
| function | 是 | 函数体 |
| let/const | 是(死区) | 未初始化 |
小结建议
为了避免变量提升带来的混乱,推荐始终在作用域顶部声明变量,优先使用let和const代替var。理解执行上下文的创建和运行两个阶段,可以让你准确预测代码行为,减少调试时间。
JavaScript变量提升执行上下文修改时间:2026-07-27 16:00:23