javascript变量如何声明_怎样正确使用let和const【教程】

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

未声明变量直接报ReferenceError。

let 和 const 声明变量时不能重复声明同一标识符

letconst 在同一个作用域内重复声明同一个变量名,会直接抛出 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 不是“常量值”,而是“不可重新赋值的绑定”。它要求声明时必须赋初始值,之后不能再用 = 赋新值。

实操注意点:

  • 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 的作用域是块级,不是函数级

letconst 只在最近的花括号 {} 内有效,包括 iffortry/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 错误
实际编码中,最容易被忽略的是 TDZ 和块级作用域的嵌套深度 —— 尤其在动态条件逻辑或异步回调里,变量看似“应该存在”,却因声明位置靠后而根本不可访问。