object.freeze仅冻结对象自身可枚举属性,不影响原型链;原型属性仍可读写,需额外切断原型链或冻结原型本身才能实现彻底不可变。

Object.freeze 只冻结对象自身的可枚举属性,**不会影响原型链上的属性**,也无法阻止对原型链的访问或修改。
它只作用于自身属性
调用 Object.freeze(obj) 后:
- 对象自身的现有属性变为不可写、不可配置、不可枚举(但已有值不变)
- 不能添加新属性,也不能删除已有属性
- 原型链完全不受影响 —— 原型上的属性仍可读、可写(如果原本可写)、可继承
原型链属性仍可被修改
例如:
const proto = { name: 'parent' };
const obj = Object.create(proto);
Object.freeze(obj);
obj.name = 'child'; // ❌ 失败:obj 自身没有 name,赋值会静默失败(严格模式报错)
proto.name = 'updated'; // ✅ 成功:修改的是原型对象,freeze 对 proto 无效
console.log(obj.name); // 'updated' —— 仍能通过原型链读到新值
想真正“隔离”原型链?得额外处理
如果目标是让对象彻底不可变(包括隔断原型影响),需组合手段:
-
切断原型链:用
Object.setPrototypeOf(obj, null)或Object.freeze(Object.create(null)) -
冻结原型本身:若控制原型对象,也对其调用
Object.freeze(proto) - 深冻结(递归):对所有嵌套对象(含原型链中可控的部分)逐层 freeze,但注意原型链通常不可控、也不应递归冻结内置原型
常见误区提醒
很多人误以为 freeze 后对象“完全不可变”,其实:
- 它不阻止通过原型修改行为(比如覆盖
toString) - 它不阻止修改原型对象本身(除非原型也被 freeze)
- 它对 getter/setter 属性仅冻结其描述符,不冻结 getter 内部逻辑
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











