让人感到疑惑的const

/ 前端

const 关键字在不同的编程语言中有着不同的含义和限制,但通常它被用来声明一个常量或只读变量。然而,在 JavaScript 中,const 的行为有时可能会让人感到困惑,因为它并不总是意味着“不可变”(immutable)。让我们详细探讨一下这个问题。

JavaScript 中的 const

在 JavaScript 中,当你使用 const 声明一个变量时,你实际上是创建了一个不能重新赋值的绑定。这意味着一旦给这个变量赋予了初始值,你就不能再将这个变量指向另一个地址或值。但是,这并不意味着该变量指向的数据结构是不可变的。

基本数据类型

对于基本数据类型(如数字、字符串、布尔值等),它们是按值存储的,因此当用 const 定义时,其值确实不可改变:

1
2
const a = 10;
a = 20; // TypeError: Assignment to constant variable.

引用数据类型

对于引用数据类型(如对象、数组等),情况就有所不同了。const 只保证变量名指向的内存地址不变,即变量名所指向的对象或数组的引用是固定的,但它所指向的对象或数组的内容是可以修改的:

1
2
3
4
5
const arr = [1, 2, 3];
arr.push(4); // 合法:修改数组内容
console.log(arr); // 输出 [1, 2, 3, 4]

arr = [5, 6, 7]; // TypeError: Assignment to constant variable.

同样的规则也适用于对象:

1
2
3
4
5
const obj = { name: 'Alice' };
obj.name = 'Bob'; // 合法:修改对象属性
console.log(obj); // 输出 { name: 'Bob' }

obj = { name: 'Charlie' }; // TypeError: Assignment to constant variable.

C/C++ 中的 const

相比之下,在C或C++中,const 更加严格地表示“只读”,试图通过任何方式修改 const 修饰的变量都会导致编译错误或者运行时错误。例如:

1
2
const int x = 10;
x = 20; // 编译错误

然而,即使在C/C++中,如果尝试通过指针绕过 const 限制,理论上也可以修改 const 变量的值,但这是一种未定义行为,应该避免这样做 。

总结

了解这一点对于正确使用 const 和维护代码的安全性和可预测性至关重要。