reflect.construct 能精准复现 class 继承中 super() 行为,通过分离实例创建与构造函数执行,并支持自定义 newtarget,使父类内 new.target 指向子类、原型链正确、super() 可递归调用。

Reflect.construct 可以精准复现 class 继承中父类构造函数的调用行为,关键在于它能同时控制 实例创建 和 构造函数执行上下文,而 new 操作符做不到这点。
理解 Reflect.construct 的核心能力
它不是简单替代 new,而是把“新建实例”和“执行构造函数”拆成可干预的两步:
- 创建一个干净、未初始化的实例(原型链已正确设置)
- 将该实例作为 this,显式调用指定构造函数
- 支持传入自定义 newTarget(影响 super() 内部行为)
复刻 extends 中 super() 的完整效果
ES6 class 继承里,子类 constructor 必须先调用 super(),否则报错;super() 不仅执行父类逻辑,还确保 this 已绑定且可被子类修改。Reflect.construct 能模拟这个约束:
- 用 Reflect.construct(Parent, args, Child) 创建实例时,newTarget 是 Child —— 这让 Parent 构造函数内 typeof this === 'object' 且 new.target === Child
- Parent 内部若用了 super()(比如 Parent 自身也继承自 GrandParent),会继续向上追溯,形成完整继承链
- 返回的实例拥有正确的 __proto__ 链:instance.__proto__ === Child.prototype,Child.prototype.__proto__ === Parent.prototype
手动实现子类构造逻辑的典型模式
不依赖 class 语法,纯函数式复刻继承流程:
function Child(...args) {
// 1. 创建实例并执行父类构造(等价于 super())
const instance = Reflect.construct(Parent, args, Child);
// 2. 在父类逻辑执行完毕后,添加子类专属初始化
instance.childProp = 'custom';
return instance;
}
Object.setPrototypeOf(Child, Parent);
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
这样做的好处是:Parent 构造函数内 this 上挂载的属性、Symbol.species 处理、Proxy 拦截等,全部按原生语义生效。
注意与 new 的关键差异
直接 new Parent(...args) 会导致 new.target === Parent,无法触发子类派生逻辑;而 Reflect.construct(Parent, args, Child) 让 Parent 内部能感知到“被子类调用”,这对依赖 new.target 的库(如某些装饰器、类型检查工具)至关重要。
不复杂但容易忽略











