const限制变量与内存地址的绑定,不阻止引用类型内部修改;基本类型因值存栈中而真正不可变,引用类型可改属性但不能重赋值。

因为 const 锁的是变量与内存地址的绑定关系,不是锁对象本身的内容。
核心区别:基本类型 vs 引用类型
JavaScript 中变量存储方式不同,决定了 const 的作用边界:
- 基本类型(string、number、boolean、null、undefined、symbol):值直接存在栈中,const 声明后,这个栈位置的值就不能改——所以真“不可变”
- 引用类型(object、array、function):变量在栈中只存一个指向堆内存的地址,const 只禁止你把地址换成另一个,但不干预堆里那个对象内部怎么变
举个直观例子
这段代码完全合法:
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
const user = { name: 'Alice', age: 30 };<br>user.age = 31; // ✅ 允许:改的是堆里的数据<br>user.city = 'Beijing'; // ✅ 允许:往原对象加属性<br>user = { name: 'Bob' }; // ❌ 报错:试图把栈中地址换成新的
为什么这样设计?
这种机制兼顾了安全与实用:
- 防止意外重赋值(比如误写
user = null导致后续逻辑崩) - 又保留对数据结构的灵活操作(增删改属性、push/pop 数组等)
- 符合函数式编程中“避免重新绑定”的理念,但不强制“深度不可变”
如果真要让对象完全不可变
需要额外手段:
-
Object.freeze(obj):冻结自身属性(浅冻结,嵌套对象仍可变) - 递归冻结或使用
structuredClone()+ 冻结组合实现深度冻结 - 用
Proxy自定义不可变代理(适合高级场景)










