let和const本质区别在于绑定不可重赋值而非值不可变:const声明后不可重新赋值但可修改对象属性,let允许重新赋值但不允许重复声明,二者均有暂时性死区。

ES6(ECMAScript 2015)不是“一堆语法糖”,而是重构了 JavaScript 的作用域、内存模型和模块行为。其中 let 和 const 是最基础也最容易误用的两个声明方式——它们不是 var 的替代品,而是为不同语义场景设计的独立工具。
let 和 const 的本质区别:绑定不可重赋值 ≠ 值不可变
const 声明的是「绑定不可重新赋值」,不是「值不可变」。这意味着:
-
const声明的对象、数组,其内部属性/元素仍可修改;只有重新赋值给该标识符会报错 -
let允许后续赋值,但不允许重复声明;const不允许重复声明,也不允许后续赋值 - 两者都存在「暂时性死区(TDZ)」:在声明前访问会抛出
ReferenceError,而非undefined
const obj = { a: 1 };
obj.a = 2; // ✅ 合法:修改属性
obj = {}; // ❌ 报错:Cannot assign to const variable
let arr = [1];
arr.push(2); // ✅ 合法:修改内容
arr = [3]; // ✅ 合法:let 允许重新赋值
什么时候必须用 let,而不是 const?
仅当变量在声明后**确定需要重新赋值**时才用 let。常见真实场景包括:
- for 循环中需要每次迭代更新的计数器(如
for (let i = 0; i ) - 异步回调中需暂存中间状态(如先设
let result,再在.then()中赋值) - 条件分支中需根据逻辑路径赋不同值(且无法用三元表达式一次性初始化)
反例:用 let 声明一个从不重新赋值的配置对象,既降低可读性,又失去 const 提供的静态检查保障。
立即学习“Java免费学习笔记(深入)”;
var 还能用吗?哪些场景下它反而更合适?
绝大多数新代码应避免 var。但它在极少数边界场景仍有意义:
- 需要函数作用域提升(hoisting)来实现「声明前可用」的兼容逻辑(如老式模块包装)
- 全局污染明确可控的脚本环境(如浏览器控制台快速调试、某些构建后的 UMD 包顶层)
- 与
with或eval配合(不推荐,仅说明存在)
注意:var 的变量提升 + 函数作用域,在块级结构(如 if、for)中极易引发意外交互。例如:
if (false) { var x = 1; }
console.log(x); // undefined —— 不是 ReferenceError,也不是 1
容易被忽略的 TDZ 细节:typeof 不再是安全操作符
在 let/const 声明前使用 typeof 会直接报错,而不再是返回 "undefined":
console.log(typeof y); // ❌ ReferenceError: Cannot access 'y' before initialization let y = 1;
这意味着你不能再靠 typeof xxx === 'undefined' 来判断变量是否存在——必须确保检查发生在声明之后,或改用 in 操作符(针对对象属性)、hasOwnProperty 或 globalThis 等更明确的方式。
真正难的不是记住 let 和 const 的语法规则,而是每次声明时问自己一句:这个绑定是否应该被重新赋值?如果答案是否定的,就该用 const;如果连这个语义都模糊,说明变量职责可能过载,得先拆逻辑。










