Object.freeze()冻结对象仅限自身属性,禁止增删改属性及描述符,但不递归冻结嵌套对象;需手动递归或借助库实现深冻结。

JavaScript 中的 对象冻结 是一种让对象“不可变”的机制,它能防止对对象本身添加、删除或修改属性,也能阻止对已有属性的值进行更改(包括属性描述符的变更)。简单说,冻结后的对象就像被锁住一样,任何试图改变它的操作都不会生效(严格模式下还会报错)。
Object.freeze() 基本用法
调用 Object.freeze(obj) 即可冻结一个对象。它会返回该对象本身(不是副本),且只影响对象自身的属性,不递归冻结嵌套对象。
- 不能添加新属性
- 不能删除已有属性
- 不能修改已有属性的值(基础类型直接卡死;引用类型值不变,但其内部仍可变)
- 不能重配置属性(如设为 writable: false 或 configurable: false 已是最终状态)
冻结 ≠ 深冻结
冻结只是浅层的。如果对象里有另一个对象,那个内层对象本身没被 freeze,依然可以修改:
const obj = { a: 1, nested: { b: 2 } };
Object.freeze(obj);
obj.a = 3; // ❌ 无效(基础值)
obj.nested.b = 99; // ✅ 有效!因为 nested 未被冻结
需要深冻结时,得手动递归调用 Object.freeze,或借助第三方库(如 deep-freeze),或用结构克隆+冻结组合方式(注意 JSON 方式会丢函数、undefined、Symbol 等)。
立即学习“Java免费学习笔记(深入)”;
其他类似方法对比
-
Object.seal():禁止增删属性,但允许改值和重配置(只要 writable 是 true) -
Object.preventExtensions():只禁止新增属性,其余都允许 -
Object.freeze()是三者中限制最严格的
它们都只作用于对象自身,都不影响原型链上的属性。
实际使用小提醒
- 冻结后
Object.isFrozen(obj)返回 true,可用于检测 - 在模块导出常量对象时常用,比如配置项、枚举对象
- 注意:冻结不会阻止对数组索引赋值(如
arr[0] = x),但会阻止push、pop等改变长度的方法 —— 因为这些方法本质是添加/删除属性 - 严格模式下尝试非法修改会抛
TypeError;非严格模式则静默失败
基本上就这些。冻结是个轻量但有效的防护手段,用对了能帮你少踩不少坑。











