const锁定变量绑定关系而非值:基本类型不可重新赋值,复合类型仅引用不可变、内部属性仍可修改;需真正冻结须配合Object.freeze()。

const 并不“锁定值”,而是“锁定变量的绑定关系”——即该变量名不能再指向另一个内存地址。它对基本类型(如数字、字符串)表现为“不可变”,但对复合类型(如对象、数组)只保证引用不变,内部属性仍可修改。
const 对基本类型:值不可再赋
基本类型(number、string、boolean、symbol、bigint、null、undefined)按值存储,const 声明后无法重新赋值:
const count = 42; count = 100; // TypeError: Assignment to constant variable.
这是因为变量 count 绑定的是具体数值 42,再次赋值会试图改变绑定目标,被禁止。
const 对对象/数组:引用不可变,内容可变
对象和数组是引用类型,const 只冻结“变量指向哪个地址”,不冻结地址里存的数据:
const user = { name: "Alice", age: 30 };
user.name = "Bob"; // ✅ 允许:修改属性
user.job = "Engineer"; // ✅ 允许:新增属性
user = {}; // ❌ 报错:不能重新赋值新对象
const list = [1, 2, 3];
list.push(4); // ✅ 允许:修改原数组
list[0] = 99; // ✅ 允许:修改元素
list = [5, 6]; // ❌ 报错:不能指向新数组
若需真正冻结复合类型,需配合 Object.freeze()
Object.freeze() 深度冻结对象自身属性(浅冻结),阻止添加、删除、修改自有属性(但不递归冻结嵌套对象):
-
Object.freeze(obj)返回同一对象,且不可逆 - 对已冻结对象赋值属性会静默失败(严格模式下报
TypeError) - 仅冻结第一层属性;若属性值是对象,其内部仍可变(需递归 freeze 或用
Object.freeze+ 深度遍历)
const config = Object.freeze({ api: "https://api.example.com", timeout: 5000 });
config.timeout = 10000; // 静默无效(非严格模式)或报错(严格模式)
config.newKey = "test"; // 同样无效
常见误区与建议
- 别误以为
const arr = []就是“不可变数组”——它只是不能=新数组,但push、splice等方法照常可用 - 需要不可变语义时,优先使用
Object.freeze或不可变库(如 Immer) - 命名习惯上,用 const 表达“此变量不会重新赋值”,而非“此值绝对不变”
- 函数参数若用 const 声明(如
function foo(obj) { const data = obj; }),同样只锁引用,不锁内容

















