JavaScript变量提升指声明在编译阶段被预处理并“准备就绪”,但赋值仍按顺序执行;var声明提升并初始化为undefined,函数声明整体提升可提前调用,let/const声明提升但不初始化,访问触发暂时性死区。

JavaScript 变量提升(Hoisting)不是“把代码往上挪”,而是指变量和函数声明在编译阶段被‘记忆’并提前‘准备就绪’,但赋值行为仍按代码顺序执行。理解它关键在于分清“声明”和“赋值”两步,以及 var、let/const 的差异。
var 声明:声明和默认值(undefined)被提升,赋值不提升
用 var 声明的变量,JS 引擎在进入作用域时就为其分配内存,并初始化为 undefined;真正的赋值(比如 a = 10)仍发生在原位置。
所以你能这样写,也不会报错:
console.log(a); // undefined<br>var a = 5;
这等价于:
立即学习“Java免费学习笔记(深入)”;
var a; // 提升:声明 + 初始化为 undefined<br>console.log(a); // undefined<br>a = 5; // 赋值:原地执行
function 声明:整个函数体被提升(可安全调用)
使用 function 关键字声明的函数(非箭头函数、非函数表达式),不仅声明被提升,函数体也一同被提升。因此可以在声明前调用:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
sayHi(); // 正常输出 "Hi!"<br>function sayHi() {<br> console.log("Hi!");<br>}
注意:如果是函数表达式(如 var greet = function() {...}),那就只提升 var greet(变成 undefined),不能提前调用。
let 和 const:声明被提升,但不初始化——暂时性死区(TDZ)
let 和 const 声明确实也被提升到块级作用域顶部,但引擎不会给它们设默认值。从作用域开始到声明语句执行前,访问它们会直接报 ReferenceError。
例如:
console.log(b); // ReferenceError: Cannot access 'b' before initialization<br>let b = 20;
这就是“暂时性死区”——不是没提升,而是提升后处于不可访问状态。这是为了防止意外使用未初始化的变量。
一句话总结关键区别
-
var:提升声明 + 初始化(
undefined),可访问,值为undefined - function 声明:提升声明 + 定义,可安全调用
- let / const:声明被提升,但不初始化,访问即报错(TDZ)
真正影响行为的是“何时初始化”和“是否允许访问未初始化状态”,而不是“代码有没有物理上移动”。记住这点,就不会被表面现象误导。

















