Object.setPrototypeOf仅改变属性查找路径起点,不修改实例自有属性:自有属性值、增删改操作均保持原样,访问行为则按新原型链即时重解析,遮蔽与删除交互遵循查找优先级,冻结对象会阻止该方法执行。

Object.setPrototypeOf 不影响实例的自有属性,只改变属性查找路径起点。对象自身的 own properties 完全不变:赋值、删除、修改都照常进行,不会因原型变更而被覆盖、清空或同步更新。
自有属性保持原样
调用 Object.setPrototypeOf 后,对象上已存在的自有属性(通过 obj.prop = value 或字面量定义)不受任何干扰:
- 原来
obj.name = "Alice",设新原型后obj.name还是 "Alice"; - 执行
delete obj.name后再读obj.name,才会沿新原型链向上查找; - 如果新原型上有同名属性,比如
newProto.name = "Bob",那obj.name会返回 "Bob" ——这不是数据被改了,而是查找时被遮蔽(shadowing)了。
属性访问行为即时变化
虽然数据没动,但“怎么读到它”立刻变了。所有依赖原型链的访问方式都会按新链重新解析:
-
obj.method():若新原型提供method,就调用它;旧原型里的同名方法不再可见; -
"prop" in obj:现在包含新原型中可枚举的继承属性,不包含旧原型中已被切断的; -
for...in循环:只遍历新原型链上的可枚举属性,旧链上的自动消失; -
Object.getPrototypeOf(obj)立即返回新设的原型对象,不是旧值。
注意遮蔽与删除的交互
自有属性和原型属性共存时,遮蔽关系由查找顺序决定,而这个顺序在 setPrototypeOf 后重置:
- 设新原型前:
obj.x = 10,oldProto.x = 20→obj.x读出 10; - 设新原型后:
newProto.x = 30→obj.x仍为 10(自有优先); - 此时执行
delete obj.x→ 再读obj.x就落到newProto.x,得 30。
冻结或不可扩展对象的限制
这些限制不改变属性本身,但会阻止 setPrototypeOf 执行,从而保护当前状态:
-
Object.freeze(obj)后调用Object.setPrototypeOf(obj, ...)抛TypeError; -
Object.preventExtensions(proto)不妨碍设原型,但之后无法向该proto添加新属性; - 传入非对象值(如数字、字符串)也会报错,
null是唯一允许的非对象值。

















