reflect.construct 是 es6 反射 api 方法,用于动态调用构造函数创建实例,支持指定自定义原型及与 proxy 的 construct 拦截器配合使用,但目标必须是可构造函数。

Reflect.construct 是 ES6 引入的反射 API 方法,用于**动态调用构造函数并创建新实例**,功能上类似 new Constructor(...args),但更灵活——它允许你显式指定原型链(即新实例的 [[Prototype]]),还能配合 Proxy 拦截构造行为。
基本用法:替代 new 的动态调用
最常见场景是把构造函数和参数作为变量传入,避免写死 new:
function Person(name) {
this.name = name;
}
const args = ['Alice'];
const instance = Reflect.construct(Person, args);
console.log(instance.name); // 'Alice'
console.log(instance instanceof Person); // true
等价于:new Person('Alice'),但参数可动态组装(比如来自配置或用户输入)。
指定自定义原型:覆盖默认 prototype
第三个参数可传入一个对象,作为新实例的 [[Prototype]](即 __proto__),绕过构造函数自身的 Constructor.prototype:
function Animal() {}
const customProto = { species: 'unknown' };
const pet = Reflect.construct(Animal, [], customProto);
console.log(pet.species); // 'unknown'
console.log(pet instanceof Animal); // false(因为原型不是 Animal.prototype)
console.log(Object.getPrototypeOf(pet) === customProto); // true
这个能力在实现继承模拟、沙箱环境或测试替身(mock)时很有用。
与 Proxy 构造拦截配合使用
当目标构造函数被 Proxy 包裹且设置了 construct 拦截器时,Reflect.construct 是推荐的“转发调用”方式,保持语义一致:
const TrackedPerson = new Proxy(Person, {
construct(target, args, newTarget) {
console.log('正在构造 Person 实例,参数:', args);
// 正确转发:保留 newTarget(影响 this.constructor 和 super 调用)
return Reflect.construct(target, args, newTarget);
}
});
const p = new TrackedPerson('Bob'); // 触发拦截,再正常构造
注意:必须传入 newTarget(通常是 Proxy 本身),否则可能破坏类继承链(尤其涉及 super() 时)。
注意事项和常见陷阱
-
不能对普通函数(非构造函数)使用:如果目标没有
[[Construct]]内部方法(如箭头函数、普通函数未用class或function声明),会抛出TypeError。 -
第三个参数不是构造函数,而是原型对象:别误传
Person.prototype以外的构造函数——那不会触发它的constructor,只是设原型。 -
不支持直接 new 代理后的普通对象:例如
Reflect.construct({})会失败,目标必须是可构造的(有[[Construct]])。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











