为什么 const 并不能冻结你的 JavaScript 数组
发布: (2025年12月11日 GMT+8 11:12)
5 min read
原文: Dev.to
Source: Dev.to

引言 – 常见的困惑
在数组上使用 const 时,感觉它应该把整个数组锁定住。可是当你尝试 push()、pop() 或者修改某个值时,数组仍然会改变。既然是常量,为什么还能变化?
答案在于 JavaScript 处理变量和引用的方式。只要弄清这两者的区别,这种行为就不再神秘,而是合乎逻辑的。
绑定 vs 值 — const 实际做了什么
const 变量就像一块牢牢插在地上的指示牌。你不能移动指示牌本身或让它指向别处,但它指向的东西可以自由移动。
- 原始类型 像是放置好的实心石块;形状不会改变。
- 数组和对象 更像是工作台:指示牌保持不动,但工作台上的工具和部件可以随意重新排列、添加或移除。
这就是核心所在。const 保护的是指针,而不是它指向的内容。
可变 vs 不可变 数据类型
- 原始类型 像封好的信封——你可以读取里面的内容,但不能更改。如果需要不同的内容,只能创建一个全新的信封。
- 对象和数组 更像打开的笔记本。你可以在同一页上写、删、添加笔记,或把内容重新排列。
这种差异解释了为什么 const 变量可以指向仍然会原地改变的数据。
具体示例 — 能做和不能做的事
const 锁定的是变量绑定,而不是值本身。这意味着你可以修改数组或对象的内容,但不能把变量重新赋值为别的东西。
const numbers = [1, 2, 3];
// ✅ 允许:改变数组本身
numbers.push(4);
numbers[0] = 10;
console.log(numbers); // [10, 2, 3, 4]
// ❌ 不允许:重新赋值变量
// numbers = [5, 6]; // TypeError: Assignment to constant variable
const person = { name: "Alice", age: 25 };
// ✅ 允许:修改属性
person.age = 26;
person.city = "Toronto";
console.log(person); // { name: "Alice", age: 26, city: "Toronto" }
// ❌ 不允许:重新赋值变量
// person = { name: "Bob" }; // TypeError
这些例子展示了关键区别:变量本身是常量,但它指向的数据可以被更新。
何时需要不可变性
有时你真的不希望数据被修改,比如在应用中共享状态或函数式编程。单靠 const 并不能阻止变更。
// 冻结对象,使其不可被修改
const person = Object.freeze({ name: "Alice", age: 25 });
person.age = 26; // ❌ 在严格模式下会被忽略
// 使用库实现更深层次的不可变性
// 例如 Immer 或 Immutable.js
锁定数据有助于防止 bug,让代码更可预测。
结论与最佳实践
- 默认使用
const;它锁定的是变量本身,而不是数据。 - 除非显式冻结,否则数组和对象仍然可以改变。
- 清晰的命名和不可变模式让代码更可预测、更易维护。
记住这些简单规则,JavaScript 就不再那么让人摸不着头脑。
参考资料 / 进一步阅读
- MDN Web Docs —
const— 官方文档,解释 JavaScript 中的变量绑定。 - MDN Web Docs — Immutable / Mutable — 词汇表,说明可变与不可变数据。
- GeeksforGeeks — JavaScript
const— 面向初学者的解释与示例。 - freeCodeCamp — Differences between
var,let, andconst— 实用指南与代码示例。 - Stack Overflow — “Keyword
constdoes not make the value immutable” — 社区讨论,澄清常见误解。