JavaScript let 和 const


Key Points

  • letconst 是 JavaScript ES6 中引入的变量声明方式,研究表明它们都具有块作用域。
  • 看起来 let 允许重新赋值,而 const 不允许,且 const 必须在声明时初始化。
  • 证据倾向于认为两者在同一作用域内不能重复声明,且不附加到全局对象。

What Are let and const?

letconst 是 JavaScript 中用于声明变量的关键字,引入于 ES6(2015 年)。

  • let:用于声明一个块作用域的变量,可以在声明后重新赋值。
  • const:用于声明一个块作用域的常量,一旦赋值后不能重新赋值,且必须在声明时初始化。

Main Differences

以下是 letconst 的主要区别:

  • 重新赋值let 可以重新赋值,const 不能。
  • 初始化要求const 必须在声明时初始化,let 可以稍后赋值。
  • 作用域:两者都具有块作用域(即只在当前代码块内有效)。
  • 重复声明:两者在同一作用域内都不能重复声明。
  • 全局对象:两者都不附加到全局对象(如浏览器中的 window),与旧的 var 不同。

详细报告

本文旨在全面解释 JavaScript 中的 letconst,它们是 ES6(ECMAScript 2015)引入的变量声明方式,旨在替代传统的 var 声明。以下将详细探讨它们的定义、特性、区别以及相关注意事项。

定义与背景

letconst 是 JavaScript 在 ES6 中新增的两个关键字,用于声明变量。它们与之前的 var 不同,主要是因为它们引入了块作用域(block scope),即变量只在它们被声明的代码块(由 {} 包裹)内有效。在 ES6 之前,JavaScript 只有全局作用域和函数作用域,这导致了一些变量作用域管理上的问题。letconst 的引入旨在解决这些问题,使代码更严谨、更易维护。

  • let:用于声明一个块作用域的变量,允许在声明后重新赋值。
  • const:用于声明一个块作用域的常量,一旦赋值后不能重新赋值,且必须在声明时初始化。

详细特性对比

以下是 letconst 的详细特性对比,包含与 var 的对比以提供背景信息,但重点在两者之间的区别。

特性letconstvar (对比参考)
作用域块作用域块作用域全局或函数作用域
可重新赋值
必须初始化
可重复声明
提升行为不提升,声明前使用报错不提升,声明前使用报错提升,初始化为 undefined
全局对象绑定不绑定(如 window不绑定(如 window绑定(如 window

从上表可以看出,letconst 的核心区别在于:

  • 重新赋值let 允许变量值被修改,例如 let x = 1; x = 2; 是合法的,而 const x = 1; x = 2; 会抛出错误。
  • 初始化要求const 必须在声明时赋值,例如 const y = 10; 是合法的,但 const z; 然后再赋值会报错。而 let 可以先声明后赋值,如 let a; a = 5;
  • 作用域:两者都具有块作用域,这意味着它们只在当前代码块(如 if 语句、for 循环内的 {})内有效。例如:
  if (true) {
    let x = 10;
    const y = 20;
  }
  console.log(x); // 报错,x 不可访问
  console.log(y); // 报错,y 不可访问

这与 var 的函数作用域或全局作用域形成对比。

其他注意事项

  • 提升(Hoisting)letconst 不会像 var 那样被提升到作用域顶部。如果在声明前使用它们,会进入“暂时性死区”(Temporal Dead Zone, TDZ),导致 ReferenceError。例如:
  console.log(x); // 报错,x 未定义
  let x = 10;

这与 var 不同,var 会初始化为 undefined,因此不会报错。

  • 全局对象绑定letconst 声明的变量不会绑定到全局对象(如浏览器中的 window),而 var 会。例如:
  var a = 1;
  let b = 2;
  console.log(window.a); // 1
  console.log(window.b); // undefined
  • const 的特殊性:虽然 const 不能被重新赋值,但如果它声明的是对象或数组,其内部属性或元素仍然可以被修改。例如:
  const arr = [1, 2, 3];
  arr.push(4); // 合法,arr 变为 [1, 2, 3, 4]
  arr = [5, 6, 7]; // 非法,报错

这意味着 const 保证的是变量引用的不可变性,而不是对象或数组内容的不可变性。

浏览器支持

两者在现代浏览器中都有广泛支持,以下是部分浏览器的最低支持版本(数据来源于 菜鸟教程 – JavaScript let 和 const):

浏览器let (最低版本)const (最低版本)
Chrome49 (2016 年 3 月)49 (2016 年 3 月)
IE / Edge12 (2015 年 7 月)11 (2013 年 10 月)
Firefox44 (2015 年 1 月)36 (2015 年 2 月)
Safari11 (2017 年 9 月)10 (2016 年 9 月)
Opera36 (2016 年 3 月)36 (2016 年 3 月)

从上表可以看出,letconst 在 2015-2017 年间的浏览器版本中开始广泛支持,当前(2025 年 6 月)几乎所有现代浏览器都完全支持。

实践中的使用建议

  • 使用 const 声明那些在整个生命周期内不会改变的变量或常量,例如数学常数(如 const PI = 3.14159;)或配置对象。
  • 使用 let 声明那些可能需要重新赋值的变量,例如循环计数器或临时变量。
  • 避免使用 var,因为它的函数作用域和提升行为容易导致意外的副作用,尤其在大型项目中。

示例代码

以下是一些示例代码,展示 letconst 的使用场景:

  • let 示例:
  let count = 0;
  count = 10; // 合法
  if (true) {
    let localVar = 5;
    console.log(localVar); // 5
  }
  console.log(count); // 10
  • const 示例:
  const MAX_VALUE = 100;
  MAX_VALUE = 200; // 非法,报错
  const obj = { name: "John" };
  obj.name = "Jane"; // 合法,对象内部可修改
  obj = { name: "Bob" }; // 非法,报错

争议与讨论

目前,letconst 的使用在 JavaScript 社区中几乎没有争议,它们被广泛认为是 var 的改进,特别是在代码可维护性和减少 bug 方面。然而,在一些遗留代码中,仍然可以看到 var 的使用,尤其是在不支持 ES6 的老旧浏览器中(尽管这种情况在 2025 年已非常少见)。此外,关于 const 是否应该用于所有不可变引用(如对象、数组)的讨论仍在继续,一些开发者建议使用不可变数据结构(如 Immutable.js)来进一步确保数据不变性。

总结

letconst 是 JavaScript 中现代化的变量声明方式,提供了块作用域和更严格的变量管理。let 适合需要重新赋值的场景,而 const 适合声明常量,尤其是在确保代码不可变性时。两者在当前浏览器中都有广泛支持,推荐在开发中优先使用它们以提高代码质量。


Key Citations


发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注