var声明变量会提升但不赋值,导致声明前访问为undefined;let/const不提升且有暂时性死区,是块级作用域;const绑定不可变但值可变,现代开发优先用const,其次let,避免var。

var 声明的变量会“提升”,但赋值不会
用 var 声明的变量,JavaScript 引擎会在作用域顶部“预声明”它(即变量提升),但初始化(赋值)仍保留在原位置。这会导致在声明前访问变量时得到 undefined,而不是报错。
常见错误现象:
console.log(a); // undefined var a = 1;看似像“先读再写”,其实不是语法错误,只是行为反直觉。
-
var允许重复声明同一变量名(不会报错,后一次覆盖前一次) - 函数作用域:在函数内用
var声明,外部不可见;但在块(如if、for)中声明,仍会泄漏到整个函数作用域 - 全局下用
var声明,会成为window的属性(浏览器环境)
let 和 const 是块级作用域,且不提升
let 和 const 不会被提升到块顶部,它们存在“暂时性死区”(TDZ):从块开始到声明语句执行前,访问该变量会直接抛出 ReferenceError。
使用场景:
if (true) {
console.log(x); // ReferenceError
let x = 1;
}
-
let可重新赋值,但不能在同一作用域重复声明 -
const必须在声明时赋值,且不能重新赋值(注意:对象或数组内容可变,只是绑定不可变) - 两者都只在
{}块内有效(if、for、独立代码块等)
const 声明的对象/数组为什么还能修改?
const 保证的是“绑定不变”,即变量名始终指向同一个内存地址,不是“值不可变”。所以对 const obj = {} 执行 obj.key = 1 合法,但 obj = {} 会报错。
容易踩的坑:
const arr = [1, 2]; arr.push(3); // ✅ 允许:修改内容 arr = [4, 5]; // ❌ TypeError:不能重新赋值
- 需要真正不可变数据时,得用
Object.freeze()或第三方库(如 Immutable.js) - 循环中用
const声明计数器(如for (const i of [1,2,3]))是安全的,每次迭代都是新绑定
实际项目中该选哪个?
现代 JavaScript 开发默认优先用 const,只有明确需要后续赋值时才降级为 let,基本不用 var。
立即学习“Java免费学习笔记(深入)”;
- 函数参数、映射结果、解构赋值——优先
const - 循环计数器、累加器、状态暂存——用
let -
var仅在需兼容极老运行时(如 IE8)且必须函数作用域时才考虑,否则就是技术债 - 注意:ESLint 规则
no-var和prefer-const能自动捕获大部分误用
最易被忽略的一点:箭头函数没有自己的 this,但 var/let/const 的作用域规则与函数是否为箭头无关——它们只看花括号和函数边界,不看函数类型。










