object.freeze()仅浅冻结对象,即只冻结第一层属性,嵌套对象仍可修改;需递归实现深冻结,且可用object.isfrozen()检测冻结状态。

JavaScript 中用 Object.freeze() 可以冻结一个对象,使其属性不可添加、不可删除、不可修改(包括属性值和属性描述符),且对象本身不能再被重新赋值为其他对象(前提是变量用 const 声明)。
基本用法:直接冻结对象
调用 Object.freeze(obj) 后,该对象变为浅冻结 —— 即只冻结第一层属性,不递归冻结嵌套对象。
- 已存在的属性无法被修改、删除或重新配置(如设为 writable: false)
- 不能添加新属性
- 对冻结对象的赋值操作(如
obj.x = 1)在严格模式下会抛出TypeError,非严格模式下静默失败
示例:
const obj = { a: 1, b: { c: 2 } };Object.freeze(obj);
obj.a = 99; // 无效(非严格模式)或报错(严格模式)
delete obj.a; // false
obj.d = 4; // 无效
obj.b.c = 99; // ✅ 仍可修改!因为 b 是引用类型,未被深层冻结
注意:Object.freeze 是浅冻结
如果对象含有嵌套对象、数组或其他引用类型,这些内部值仍可被修改。需要深层冻结时,得手动递归处理。
- 常见误区:以为
Object.freeze()能锁死整个数据结构 - 数组也是对象,
Object.freeze(arr)可阻止增删改元素,但若数组里存了对象,那些对象依然可变
示例(数组):
Object.freeze(arr);
arr.push('world'); // 失败
arr[0].name = 'Bob'; // ✅ 成功 —— 冻结没进到内部对象
如何实现真正“不可变”的深度冻结?
没有内置的深冻结方法,但可以写一个简单递归函数(适用于普通对象/数组,不含函数、Date、RegExp 等特殊类型):
- 先检查是否为对象且非 null、非数组/日期/正则等(避免意外冻结内置行为)
- 对每个属性值,如果是对象,先递归冻结它,再调用
Object.freeze - 最后冻结父对象自身
简易实现:
function deepFreeze(obj) {if (obj && typeof obj === 'object') {
Object.getOwnPropertyNames(obj).forEach(prop => {
if (obj[prop] && typeof obj[prop] === 'object') {
deepFreeze(obj[prop]);
}
});
}
return Object.freeze(obj);
}
冻结后还能判断对象是否被冻结吗?
可以用 Object.isFrozen() 检查:
-
Object.isFrozen(obj)返回true表示对象已冻结(所有自有属性都不可配置、不可写) - 注意:它只检测当前对象状态,不关心是否深冻结
- 对非对象(如字符串、数字)调用会返回
true(因为原始值本就不可变)
示例:
const o = { x: 1 };console.log(Object.isFrozen(o)); // false
Object.freeze(o);
console.log(Object.isFrozen(o)); // true
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











