const

const 声明用于声明块作用域的局部变量。常量的值不能通过使用赋值运算符重新赋值来更改,但是如果常量是一个对象,它的属性可以被添加、更新或删除。

尝试一下

语法

js
const name1 = value1;
const name1 = value1, name2 = value2;
const name1 = value1, name2 = value2, /* …, */ nameN = valueN;
nameN

要声明的变量的名称。每个变量名称必须是合法的 JavaScript 标识符解构绑定模式

valueN

变量的初始值。它可以是任何合法的表达式。

描述

const 声明与 let 非常相似:

  • const 声明的作用域既可以是块级作用域,也可以是函数作用域。
  • const 声明只有在声明的位置之后才能访问(参见暂时性死区)。因此,const 声明通常被视为非提升的声明方式。
  • 当在脚本的顶层声明时,const 声明不会在 globalThis 上创建属性。
  • 在同一作用域中,const 声明不能被任何其他声明重新声明
  • const声明而不是语句。这意味着你不能将单独的 const 声明用作块的主体(这是合理的,因为无法访问变量)。
    js
    if (true) const a = 1; // SyntaxError: Lexical declaration cannot appear in a single-statement context
    

一个常量需要一个初始值。你必须在声明同时指定它的值。(这是合理的,因为它在声明后不能被改变。)

js
const FOO; // SyntaxError: Missing initializer in const declaration

const 声明创建了一个对值的不可变引用。它并意味着它所持有的值是不可变的,只是变量标识符不能被重新赋值。例如,在内容是对象的情况下,这意味着对象的内容(例如属性)是可以被修改的。你应该将 const 声明理解为“创建一个身份保持不变”的标识符(变量),而不是“保持不变的标识符”——换言之,是“创建不可变的绑定”,而不是“不可变的值”。

许多代码风格指南(包括 MDN 的指南建议当变量在其作用域中不会重新赋值时使用 const 而不是 let。这样可以清晰地表达变量的类型(或值,如果是原始类型的情况下)永远不会改变的意图。对非原始值可能改变的情况下其他人可能更喜欢使用 let

紧跟在 const 关键字后面的列表被称为绑定列表,用逗号分隔,其中逗号不是逗号运算符= 符号不是赋值运算符。后面变量的初始值可以引用处在列表前面的变量。

示例

const 基本用法

常量在声明的时候可以使用大小写,但通常情况下全部用大写字母,特别是对于原始值,因为它们确实是不可变的。

js
// 定义常量 MY_FAV 并赋值为 7
const MY_FAV = 7;

console.log(`我最喜欢的数字是:${MY_FAV}`);
js
// 对常量变量重新赋值会引发错误
MY_FAV = 20; // TypeError: Assignment to constant variable

// 重新声明常量会引发错误
const MY_FAV = 20; // SyntaxError: Identifier 'MY_FAV' has already been declared
var MY_FAV = 20; // SyntaxError: Identifier 'MY_FAV' has already been declared
let MY_FAV = 20; // SyntaxError: Identifier 'MY_FAV' has already been declared

块级作用域

请务必注意块作用域的特性。

js
const MY_FAV = 7;

if (MY_FAV === 7) {
  // 没有问题,因为它在新的块级作用域中
  const MY_FAV = 20;
  console.log(MY_FAV); // 20

  // var 声明的范围不限于块,因此会引发错误
  var MY_FAV = 20; // SyntaxError: Identifier 'MY_FAV' has already been declared
}

console.log(MY_FAV); // 7

定义对象和数组常量

const 也适用于对象和数组。尝试覆盖该对象会引发错误“Assignment to constant variable”。

js
const MY_OBJECT = { key: "值" };
MY_OBJECT = { OTHER_KEY: "值" };

然而,对象的键不受保护,因此以下语句可以正常执行。

js
MY_OBJECT.key = "其他值";

你可能需要使用 Object.freeze() 来使对象不可变。

这对数据同样适用。尝试覆盖该数组会引发错误“Assignment to constant variable”。

js
const MY_ARRAY = [];
MY_ARRAY = ["B"];

同样地,数组的元素不受保护,因此以下语句可以正常执行。

js
MY_ARRAY.push("A"); // ["A"]

带解构赋值的声明

每个 = 后面的左侧也可以是绑定模式。这允许一次创建多个变量。

js
const result = /(a+)(b+)(c+)/.exec("aaabcc");
const [, a, b, c] = result;
console.log(a, b, c); // "aaa" "b" "cc"

有关更多信息,请参阅解构赋值

规范

Specification
ECMAScript Language Specification
# sec-let-and-const-declarations

浏览器兼容性

BCD tables only load in the browser

参见