为什么 const 并不能冻结你的 JavaScript 数组

发布: (2025年12月11日 GMT+8 11:12)
5 min read
原文: Dev.to

Source: Dev.to

Cover image for Why const Doesn’t Freeze Your JavaScript Arrays

引言 – 常见的困惑

在数组上使用 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 就不再那么让人摸不着头脑。

参考资料 / 进一步阅读

Back to Blog

相关文章

阅读更多 »