const锁住的是变量绑定而非值本身,即地址不可变但内容可变;基本类型值存于栈,引用类型存地址,故对象属性和数组元素可修改,但重新赋值会报错;需用object.freeze等实现真正不可变。

const 声明的对象内部属性能改,是因为 const 锁住的是“变量绑定”,不是“值本身”。
const 保证的是地址不变,不是内容不可变
JavaScript 中,基本类型(如数字、字符串)的值直接存在变量指向的内存位置;而对象和数组属于引用类型,变量里存的只是一个指向堆内存中真实数据的地址。
const 的作用是禁止你把变量重新指向另一个地址——也就是不能做 obj = {} 或 arr = [] 这类赋值操作。但只要地址没变,往这个地址所指的对象里增删改属性、往数组里 push/pop/splice 元素,都是允许的。
常见可修改的操作(不会报错)
const user = { name: 'Alice' }; user.name = 'Bob';const list = [1, 2]; list.push(3); list[0] = 99;Object.defineProperty(user, 'age', { value: 30 });delete user.name;
哪些操作会报错?
-
user = { name: 'Charlie' };→ 报Assignment to constant variable -
list = [4, 5];→ 同样报错 -
Object.assign(user, { name: 'Dave' });→ 不报错(只是改属性,没换地址)
想真正冻结对象怎么办?
如果确实需要让对象完全不可变,得配合原生 API:
-
Object.freeze(obj):阻止新增、删除、修改已有属性(浅冻结) -
Object.seal(obj):阻止新增/删除,但允许改现有属性值 - 深层冻结需递归调用
freeze,或使用第三方库如immer管理不可变更新
本质上,const 是语法层的绑定保护,不是数据层的不可变保障。理解这点,就不会误以为 “const 对象=彻底只读”了。











