const仅提供变量绑定不可变的浅层保护,对象属性(含嵌套)仍可修改;真正禁止修改需用Object.freeze()递归实现深度冻结。

ES6 的 const 只能保证变量绑定不可变,即不能重新赋值给该变量名,但**不等于对象内容不可变**。要真正禁止修改对象的属性(包括嵌套对象),必须配合 Object.freeze() 并递归处理——也就是“深度冻结”。
const 声明对象只是浅层保护
用 const 声明一个对象,只能防止你把整个变量指向另一个新对象:
-
const user = { name: 'Alice', profile: { age: 30 } };✅ 合法 -
user.name = 'Bob';✅ 允许(属性可改) -
user.profile.age = 31;✅ 允许(嵌套属性也可改) -
user = { name: 'Charlie' };❌ 报错:Assignment to constant variable
Object.freeze() 实现单层冻结
Object.freeze(obj) 会冻结对象自身:禁止添加、删除、修改已有属性(严格模式下赋值会报错,非严格模式静默失败)。
const user = Object.freeze({ name: 'Alice', profile: { age: 30 } });-
user.name = 'Bob';→ 不生效(非严格模式)或报错(严格模式) -
user.profile.age = 31;→ 仍然生效!因为profile本身没被冻结
手动实现深度冻结函数
要冻结所有嵌套层级,需递归调用 Object.freeze()。注意只对纯对象(typeof === 'object' 且非 null)操作,避免冻结数组、Date、RegExp 等特殊对象(如需支持,应单独判断):
const deepFreeze = (obj) => {
Object.freeze(obj);
Object.keys(obj).forEach(key => {
if (obj[key] !== null && typeof obj[key] === 'object') {
deepFreeze(obj[key]);
}
});
return obj;
};
const config = deepFreeze({
api: { baseUrl: 'https://api.example.com', timeout: 5000 },
features: { darkMode: true, analytics: false }
});
config.api.baseUrl = 'hacked'; // 无效
config.features.darkMode = false; // 无效
声明时直接深度冻结更安全
推荐在 const 声明的同时完成深度冻结,避免中间状态被意外修改:
- ❌ 分两步写风险高:
const data = { a: { b: 1 } };<br>deepFreeze(data); // 若中间有其他代码,data 可能已被改 - ✅ 一步到位更可靠:
const data = deepFreeze({ a: { b: 1 } });


















