let和const禁止重复声明、必须初始化且不可重新赋值,作用域为块级,存在暂时性死区(TDZ),访问未声明变量直接报ReferenceError。

let 和 const 声明变量时不能重复声明同一标识符
用 let 或 const 在同一个作用域内重复声明同一个变量名,会直接抛出 SyntaxError: Identifier 'xxx' has already been declared。这和 var 的变量提升+重复声明静默忽略完全不同。
常见踩坑场景:
- 在 for 循环外手动写了一次
let i = 0,又在for (let i = 0; ...)中再次声明 —— 报错 - 模块顶部写了
const API_URL = '...',又在某个函数里写了同名const API_URL = '...'(如果没块级作用域包裹)—— 报错 - 使用
import引入的绑定名(如import { foo } from './x.js'),再用const foo = ...覆盖 —— 报错
const 声明的变量必须初始化,且不能重新赋值
const 不是“常量值”,而是“不可重新赋值的绑定”。它要求声明时必须赋初始值,之后不能再用 = 赋新值。
实操注意点:
立即学习“Java免费学习笔记(深入)”;
-
const obj;→ 语法错误,必须写成const obj = {}; -
const arr = [1, 2]; arr.push(3);→ 合法,因为没改变arr这个绑定,只是修改了对象内容 -
const arr = [1, 2]; arr = [3, 4];→ 报TypeError: Assignment to constant variable - 想冻结内容?得配合
Object.freeze()或const+ 不可变数据结构(如Immutable.js或现代structuredClone后操作)
let/const 的作用域是块级,不是函数级
let 和 const 只在最近的花括号 {} 内有效,包括 if、for、try/catch 块,而不仅是函数体。这是它们和 var 最本质的区别。
典型影响:
-
if (true) { let x = 1; } console.log(x);→ 报ReferenceError: x is not defined(不是undefined) -
for (let i = 0; i console.log(i), 0);→ 正确输出0, 1, 2;若换成var i,则输出三个3 -
try { throw new Error(); } catch (err) { let msg = err.message; } console.log(msg);→ 报错,msg出了catch块就不可见
暂时性死区(TDZ)让 let/const 在声明前访问直接报错
在块内,从块开始到 let/const 声明语句执行前,该变量处于“暂时性死区”:不能读、不能写、甚至不能用 typeof 安全检测。
这意味着:
-
console.log(a); let a = 1;→ReferenceError,不是undefined -
typeof a;在let a前执行 → 同样报ReferenceError(区别于var a时返回"undefined") - 箭头函数中若引用了外部块级声明的
let/const,但该声明还没执行到,调用时仍会触发 TDZ 错误











