Reflect.setPrototypeOf 是 ES6 标准化方法,用于安全修改对象原型,接收目标对象和新原型两个参数,成功返回 true、失败返回 false;相比非标准的 proto 更规范,且不静默失败。

Reflect.setPrototypeOf 是 JavaScript 中用于动态修改对象原型的标准化方法,它比直接操作 __proto__ 更安全、更规范,且在严格模式下也能正常工作。
基本用法和返回值
该方法接收两个参数:目标对象和新的原型对象,成功时返回 true,失败(如目标不可扩展或新原型非法)时返回 false:
Reflect.setPrototypeOf(obj, newPrototype)- 如果
obj是不可扩展的(Object.isExtensible(obj) === false),操作会失败 - 如果
newPrototype不是对象且不为null,也会抛出TypeError
与 __proto__ 和 Object.setPrototypeOf 的区别
Reflect.setPrototypeOf 和 Object.setPrototypeOf 功能一致,但前者是 Reflect API 的一部分,设计上更强调“操作是否成功”的语义,返回布尔值便于判断;而后者失败时直接抛异常。相比非标准的 __proto__:
-
__proto__是历史遗留属性,存在性能隐患且部分环境(如某些严格模式或优化引擎)不推荐使用 -
Reflect.setPrototypeOf是 ES6 标准方法,行为明确、可预测 - 它不会静默失败——返回
false提示你检查对象状态(如是否被冻结)
常见使用场景和注意事项
适用于需要运行时切换行为的场景,比如模拟继承、插件系统或测试中临时替换原型:
立即学习“Java免费学习笔记(深入)”;
- 确保目标对象可扩展:
Object.preventExtensions()、Object.seal()或Object.freeze()后无法修改原型 - 新原型可以是
null(创建无原型对象),也可以是普通对象、函数的prototype,甚至另一个实例 - 注意原型链变更后,已存在的属性访问不受影响,但后续的
in、hasOwnProperty、instanceof等会反映新链
简单示例
以下代码演示如何将一个普通对象的原型设为 Array.prototype,从而让它能调用 push 等方法:
const obj = {};
const success = Reflect.setPrototypeOf(obj, Array.prototype);
console.log(success); // true
console.log(obj.push(1, 2)); // 2
console.log(Array.isArray(obj)); // false(instanceof 仍为 false,因为 constructor 未改)
注意:instanceof 判断依赖构造函数,仅改原型不会改变 constructor 属性,如需完全模拟,还需手动设置 obj.constructor = Array。


















