不能对被冻结对象使用object.setprototypeof,非严格模式静默失败,严格模式抛typeerror;因冻结后[[prototype]]被标记为不可写,替代方案是创建继承新原型的新对象。

不能对被冻结对象使用 Object.setPrototypeOf,调用会静默失败(非严格模式)或抛出 TypeError(严格模式)。
被冻结对象的不可变性是根本原因
调用 Object.freeze(obj) 后,对象的内部属性 [[Prototype]] 会被标记为不可写(non-writable),同时对象自身变为不可扩展、所有自有属性变为不可配置且不可写。由于 Object.setPrototypeOf 的本质是修改 [[Prototype]] 内部槽位,而该操作在冻结对象上被明确禁止,因此无法生效。
不同模式下的具体表现
- 在非严格模式下:
Object.setPrototypeOf(frozenObj, newProto)返回frozenObj,但原型链未改变,也不报错; - 在严格模式下:同一调用会立即抛出
TypeError: Cannot set property __proto__ of a frozen object类似提示; - 无论是否严格模式,
Object.getPrototypeOf(frozenObj)始终返回原始原型,验证修改未发生。
替代方案需绕过冻结限制
若确实需要变更原型,唯一可行路径是创建新对象并继承所需原型,而非修改原冻结对象:
- 用
Object.create(newProto, descriptors)手动重建对象结构; - 用展开语法或
Object.assign复制自有属性,再指定新原型; - 注意:这生成的是新对象,原冻结对象仍保持不变——符合冻结语义的设计初衷。
检查是否可设置原型的实用方法
可通过 Object.isExtensible 和属性描述符判断,但更直接的方式是尝试设置并捕获异常:
-
Object.isFrozen(obj)为true时,setPrototypeOf必定失败; - 即使未冻结,若对象不可扩展且当前
[[Prototype]]为null,也可能失败; - 生产环境建议先做防御性检查,避免静默失败导致逻辑错误。
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











