const
关键字在不同的编程语言中有着不同的含义和限制,但通常它被用来声明一个常量或只读变量。然而,在 JavaScript 中,const
的行为有时可能会让人感到困惑,因为它并不总是意味着“不可变”(immutable)。让我们详细探讨一下这个问题。
JavaScript 中的 const
在 JavaScript 中,当你使用 const
声明一个变量时,你实际上是创建了一个不能重新赋值的绑定。这意味着一旦给这个变量赋予了初始值,你就不能再将这个变量指向另一个地址或值。但是,这并不意味着该变量指向的数据结构是不可变的。
基本数据类型
对于基本数据类型(如数字、字符串、布尔值等),它们是按值存储的,因此当用 const
定义时,其值确实不可改变:
const a = 10;
a = 20; // TypeError: Assignment to constant variable.
引用数据类型
对于引用数据类型(如对象、数组等),情况就有所不同了。const
只保证变量名指向的内存地址不变,即变量名所指向的对象或数组的引用是固定的,但它所指向的对象或数组的内容是可以修改的:
const arr = [1, 2, 3];
arr.push(4); // 合法:修改数组内容
console.log(arr); // 输出 [1, 2, 3, 4]
arr = [5, 6, 7]; // TypeError: Assignment to constant variable.
同样的规则也适用于对象:
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
修饰的变量都会导致编译错误或者运行时错误。例如:
const int x = 10;
x = 20; // 编译错误
然而,即使在C/C++中,如果尝试通过指针绕过 const
限制,理论上也可以修改 const
变量的值,但这是一种未定义行为,应该避免这样做 。
总结
- 在 JavaScript 中,
const
确保的是变量绑定的不可变性,而不是其所指向的数据结构的不可变性。 - 若要使对象或数组本身成为不可变的,可以使用
Object.freeze()
方法来冻结对象,防止其属性被修改 。 - 在C/C++中,
const
提供了更强的保护,防止变量被修改,但在某些情况下,仍然可以通过非标准手段修改这些值,这应当被视为不安全的做法。
了解这一点对于正确使用 const
和维护代码的安全性和可预测性至关重要。