Object.setPrototypeOf仅修改对象的[[Prototype]]指针,不影响自有属性、属性特性、不可枚举属性、getter/setter、闭包变量及WeakMap数据;行为变化源于查找路径切换,而非状态重置;instanceof等链相关操作立即生效;状态重置需手动处理。

Object.setPrototypeOf 只改对象的 [[Prototype]] 指针,不碰实例自身的任何状态——自有属性、属性特性(writable/configurable)、不可枚举字段、闭包变量、WeakMap 关联数据,全都不受影响。所谓“状态变化”,其实是查找路径变了,不是数据被重置或覆盖。
自有属性完全保留,值和特性都不变
对象身上已有的东西,一个都不会丢,也不会自动更新:
- 普通属性照常访问:obj.x = 10,设新原型后 obj.x 还是 10;
- defineProperty 定义的特性不受影响:{ value: 5, writable: false } 的属性,改完原型后依然不可写;
- 不可枚举属性仍在:用 Object.defineProperty 添加的 enumerable: false 属性,for...in 看不见,但 obj.prop 仍能读取;
- getter/setter 不会重绑定:已有访问器保持原行为,不会因原型变更而重新触发或失效。
行为变化来自查找路径切换,不是状态重置
看起来“变样了”,是因为属性和方法现在从新原型上找:
- 如果新原型上有同名属性(比如 proto.x = 20),obj.x 就会返回 20 —— 这叫遮蔽(shadowing),不是覆盖原有值;
- 删掉 obj.x 后再读 obj.x,就会落到新原型上取值,这是查找链生效,不是状态被“刷新”;
- toString()、valueOf() 等方法调用结果可能不同,因为现在走的是新原型上的实现,而非 Object.prototype 上的默认版本。
instanceof 和 isPrototypeOf 立即反映新链
这些判断依赖原型链结构,所以一设就变:
- obj instanceof SomeClass 可能从 true 变 false,只要 SomeClass.prototype 不再在新链上;
- SomeClass.prototype.isPrototypeOf(obj) 返回值会翻转;
- Object.getPrototypeOf(obj) 立刻返回你传入的新原型对象;
- for...in 遍历结果也会变——新增/消失的可枚举继承属性实时体现。
真正需要“重置状态”的,得手动做
setPrototypeOf 不负责清理,它只改“往哪找”。如果你希望实例回到初始态,得自己处理:
- 删除自有属性:
delete obj.key或遍历Object.keys(obj)清空; - 恢复默认值:显式赋值,或用工厂函数重建干净实例;
- 清理私有状态:比如 WeakMap 缓存、定时器、事件监听器,都得单独释放;
- 注意:原型上误存的状态(如 proto.cache = new Map())会让本该回收的实例滞留,引发内存问题。

















