object.setprototypeof 的核心作用是直接修改对象的 [[prototype]] 内部插槽,就地变更单个对象实例的隐式原型,不影响构造函数的 prototype 属性或其他实例。

Object.setPrototypeOf 的核心作用是直接修改对象内部的 [[Prototype]] 内部插槽,它不创建新对象,而是就地变更指定对象的原型链起点。
它改的是什么?不是构造函数的 prototype
这个方法操作的是**单个对象实例**的隐式原型(即 [[Prototype]]),和构造函数的 prototype 属性完全无关。比如:
- 给
let obj = {}设置新原型,只影响obj自己; -
obj.constructor.prototype不变,其他同构造函数创建的实例也不受影响; - 甚至构造函数本身(作为 Function 实例)也能被设为某个对象的原型,但它自身的
prototype属性依然独立存在。
参数校验与边界行为
调用时会做严格检查:
- 第一个参数
obj必须是对象(null和undefined会报错); - 第二个参数
proto必须是对象或null;传入原始值(如字符串、数字、undefined)会被静默忽略(不报错但无效); - 如果目标对象已被设为不可扩展(
Object.isExtensible(obj) === false),则抛出TypeError; - 成功后返回原对象(不是副本),即它是“就地修改”且返回自身。
和 __proto__ 的关系
Object.setPrototypeOf(obj, proto) 是 obj.__proto__ = proto 的标准化替代方案:
-
__proto__是非标准但广泛支持的访问器属性,本质调用的就是Object.getPrototypeOf/Object.setPrototypeOf; - ES6 明确推荐用
Object.setPrototypeOf()替代赋值__proto__,因其语义清晰、行为规范、便于引擎优化; - 两者在效果上等价,但
Object.setPrototypeOf()更安全——例如在严格模式下对__proto__赋值可能静默失败,而该方法会明确报错。
性能与使用提醒
这不是一个轻量操作:
- V8 等引擎会对原型链变更做缓存失效处理,频繁调用会影响内联缓存(IC)效率,拖慢后续属性访问;
- 若只是想让新对象继承某原型,优先用
Object.create(proto),它在创建阶段一次性设定,更高效; - 生产环境应避免在热路径中反复修改已有对象的原型,尤其在循环或高频事件中。











