Object.setPrototypeOf 是 ES6+ 标准方法,用于直接修改对象的 [[Prototype]],接受目标对象和新原型两个参数,成功返回目标对象,失败抛出 TypeError;它替代了非标准的 __proto__,但不可用于冻结或不可扩展的对象,且频繁调用影响性能。

Object.setPrototypeOf 是 JavaScript 中用于**直接修改对象的原型(即 [[Prototype]] 内部属性)**的标准方法。它接受两个参数:目标对象和新的原型对象,成功时返回该目标对象,失败(如目标不可扩展且新原型不匹配)则抛出 TypeError。
基本用法:替换对象的原型
你可以用它把一个普通对象的原型指向另一个对象或构造函数的 prototype:
const parent = { sayHello() { return 'Hello'; } };
const child = { name: 'Alice' };
Object.setPrototypeOf(child, parent);
console.log(child.sayHello()); // 'Hello'
console.log(Object.getPrototypeOf(child) === parent); // true
替代 __proto__ 的标准方式
__proto__ 虽然广泛支持,但它是**遗留属性,非 ECMAScript 标准(仅作为规范附录存在),不推荐在生产中使用**。而 Object.setPrototypeOf 是 ES6+ 正式引入的标准 API,语义明确、行为可靠:
- ✅ 明确表达“设置原型”的意图
- ✅ 在严格模式下安全可用(
__proto__在某些环境下可能被禁用或只读) - ❌ 不可用于已冻结(
Object.freeze())或不可扩展(Object.preventExtensions())的对象
常见注意事项与限制
使用时需注意以下几点,避免运行时错误:
- 目标对象必须是普通对象(不能是
null或原始值) - 若目标对象已被
Object.seal()或Object.freeze(),无法修改其原型 - 新原型可以是任意对象,包括
null(此时对象无原型,Object.getPrototypeOf(obj) === null) - 频繁调用会影响性能(V8 等引擎会将对象标记为“原型已变更”,可能退出优化)
创建对象时就指定原型(更优实践)
如果目的是让新对象继承某原型,优先考虑更高效、更语义化的方式:
- 用
Object.create(proto)创建带指定原型的新对象 - 用
class/ 构造函数 +extends实现继承 - 避免对已有对象反复修改原型——这通常意味着设计可改进
例如:
// 推荐:创建时设定
const obj = Object.create({ method() { return 42; } });
// 而非创建后再改
const obj2 = {};
Object.setPrototypeOf(obj2, { method() { return 42; } });











