Skip to content

Commit

Permalink
[zh-cn]: update the translation of const in statement section (#18798)
Browse files Browse the repository at this point in the history
  • Loading branch information
JasonLamv-t authored Mar 21, 2024
1 parent c88f17b commit 9f08ca0
Showing 1 changed file with 80 additions and 57 deletions.
137 changes: 80 additions & 57 deletions files/zh-cn/web/javascript/reference/statements/const/index.md
Original file line number Diff line number Diff line change
@@ -1,116 +1,139 @@
---
title: const
slug: Web/JavaScript/Reference/Statements/const
l10n:
sourceCommit: 4f86aad2b0b66c0d2041354ec81400c574ab56ca
---

{{jsSidebar("Statements")}}

常量是块级范围的,非常类似用 [let](/zh-CN/docs/Web/JavaScript/Reference/Statements/let) 语句定义的变量。但常量的值是无法(通过重新赋值)改变的,也不能被重新声明
**`const`** 声明用于声明块作用域的局部变量。常量的值不能通过使用[赋值运算符](/zh-CN/docs/Web/JavaScript/Reference/Operators/Assignment)重新赋值来更改,但是如果常量是一个[对象](/zh-CN/docs/Web/JavaScript/Data_structures#objects),它的属性可以被添加、更新或删除

{{EmbedInteractiveExample("pages/js/statement-const.html")}}

## 语法

```plain
const name1 = value1 [, name2 = value2 [, ... [, nameN = valueN]]];
```js-nolint
const name1 = value1;
const name1 = value1, name2 = value2;
const name1 = value1, name2 = value2, /* …, */ nameN = valueN;
```

- `nameN`
- : 常量名称,可以是任意合法的{{Glossary("identifier","标识符")}}
- : 要声明的变量的名称。每个变量名称必须是合法的 JavaScript [标识符](/zh-CN/docs/Web/JavaScript/Reference/Lexical_grammar#标识符)[解构绑定模式](/zh-CN/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)
- `valueN`
- : 常量值,可以是任意合法的表达式
- : 变量的初始值。它可以是任何合法的表达式

## 描述

此声明创建一个常量,其作用域可以是全局或本地声明的块。与[`var`](/zh-CN/docs/Web/JavaScript/Reference/Statements/var)变量不同,全局常量不会变为 window 对象的属性。需要一个常数的初始化器;也就是说,你必须在声明的同一语句中指定它的值(这是有道理的,因为以后不能更改)。
`const` 声明与 {{jsxref("Statements/let", "let")}} 非常相似:

**`const` 声明**创建一个值的只读引用。但这并不意味着它所持有的值是不可变的,只是变量标识符不能重新分配。例如,在引用内容是对象的情况下,这意味着可以改变对象的内容(例如,其参数)。
- `const` 声明的作用域既可以是块级作用域,也可以是函数作用域。
- `const` 声明只有在声明的位置之后才能访问(参见[暂时性死区](/zh-CN/docs/Web/JavaScript/Reference/Statements/let#暂时性死区))。因此,`const` 声明通常被视为[非提升](/zh-CN/docs/Glossary/Hoisting)的声明方式。
- 当在脚本的顶层声明时,`const` 声明不会在 {{jsxref("globalThis")}} 上创建属性。
- 在同一作用域中,`const` 声明不能被任何其他声明[重新声明](/zh-CN/docs/Web/JavaScript/Reference/Statements/let#重新声明)
- `const`[*声明*而不是*语句*](/zh-CN/docs/Web/JavaScript/Reference/Statements#语句和声明的区别)。这意味着你不能将单独的 `const` 声明用作块的主体(这是合理的,因为无法访问变量)。

关于“[暂存死区](/zh-CN/docs/Web/JavaScript/Reference/Statements/let#Temporal_dead_zone_and_errors_with_let)”的所有讨论都适用于[`let`](/zh-CN/docs/Web/JavaScript/Reference/Statements/let)`const`
```js-nolint example-bad
if (true) const a = 1; // SyntaxError: Lexical declaration cannot appear in a single-statement context
```

一个常量不能和它所在作用域内的其他变量或函数拥有相同的名称。
一个常量需要一个初始值。你必须在声明同时指定它的值。(这是合理的,因为它在声明后不能被改变。)

```js-nolint example-bad
const FOO; // SyntaxError: Missing initializer in const declaration
```

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

许多代码风格指南(包括 [MDN 的指南](/zh-CN/docs/MDN/Writing_guidelines/Writing_style_guide/Code_style_guide/JavaScript#变量声明)建议当变量在其作用域中不会重新赋值时使用 `const` 而不是 {{jsxref("Statements/let", "let")}}。这样可以清晰地表达变量的类型(或值,如果是原始类型的情况下)永远不会改变的意图。对非原始值可能改变的情况下其他人可能更喜欢使用 `let`

紧跟在 `const` 关键字后面的列表被称为[_绑定_](/zh-CN/docs/Glossary/Binding)_列表_,用逗号分隔,其中逗号*不是*[逗号运算符](/zh-CN/docs/Web/JavaScript/Reference/Operators/Comma_operator)`=` 符号*不是*[赋值运算符](/zh-CN/docs/Web/JavaScript/Reference/Operators/Assignment)。后面变量的初始值可以引用处在列表前面的变量。

## 示例

### const 基本用法

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

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

// 报错 - Uncaught TypeError: Assignment to constant variable.
MY_FAV = 20;

// MY_FAV is 7
console.log("my favorite number is: " + MY_FAV);

// 尝试重新声明会报错
// Uncaught SyntaxError: Identifier 'MY_FAV' has already been declared
const MY_FAV = 20;
console.log(`我最喜欢的数字是:${MY_FAV}`);
```

// MY_FAV 保留给上面的常量,这个操作会失败
var MY_FAV = 20;
```js-nolint example-bad
// 对常量变量重新赋值会引发错误
MY_FAV = 20; // TypeError: Assignment to constant variable
// 也会报错
let MY_FAV = 20;
// 重新声明常量会引发错误
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
if (MY_FAV === 7) {
// 没问题,并且创建了一个块作用域变量 MY_FAV
// (works equally well with let to declare a block scoped non const variable)
let MY_FAV = 20;
```js-nolint
const MY_FAV = 7;
// MY_FAV 现在为 20
console.log("my favorite number is " + MY_FAV);
if (MY_FAV === 7) {
// 没有问题,因为它在新的块级作用域中
const MY_FAV = 20;
console.log(MY_FAV); // 20
// 这被提升到全局上下文并引发错误
var MY_FAV = 20;
// var 声明的范围不限于块,因此会引发错误
var MY_FAV = 20; // SyntaxError: Identifier 'MY_FAV' has already been declared
}
// MY_FAV 依旧为 7
console.log("my favorite number is " + MY_FAV);
console.log(MY_FAV); // 7
```

### 常量要求一个初始值
### 定义对象和数组常量

```js
// 报错
// Uncaught SyntaxError: Missing initializer in const declaration
`const` 也适用于对象和数组。尝试覆盖该对象会引发错误“Assignment to constant variable”。

const FOO;
```js example-bad
const MY_OBJECT = { key: "" };
MY_OBJECT = { OTHER_KEY: "" };
```

### 常量可以定义成对象和数组

常量可以定义成对象和数组
然而,对象的键不受保护,因此以下语句可以正常执行。

```js
const MY_OBJECT = { key: "value" };
MY_OBJECT.key = "其他值";
```

// 重写对象和上面一样会失败
// Uncaught TypeError: Assignment to constant variable.
MY_OBJECT = { OTHER_KEY: "value" };
你可能需要使用 {{jsxref("Object.freeze()")}} 来使对象不可变。

// 对象属性并不在保护的范围内
// 下面这个声明会成功执行
MY_OBJECT.key = "otherValue"; // Use Object.freeze() to make object immutable
这对数据同样适用。尝试覆盖该数组会引发错误“Assignment to constant variable”。

// 也可以用来定义数组
```js example-bad
const MY_ARRAY = [];
// 可以向数组填充数据
MY_ARRAY.push("A"); // ["A"]
// 但是,将一个新数组赋给变量会引发错误
// Uncaught TypeError: Assignment to constant variable.
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"
```

有关更多信息,请参阅[解构赋值](/zh-CN/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)

## 规范

{{Specifications}}
Expand Down

0 comments on commit 9f08ca0

Please sign in to comment.