You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript无class语法时如何调用强制要求new的父构造函数

问题根源

你惯用的ES5继承写法仅适配老式构造函数:这类构造函数不校验调用方式,且会直接在传入的this对象上挂载属性。但ES6新增的内置类(如MediaSource)、所有用class定义的构造函数都带有[[IsClassConstructor]]内部标记:

  • 禁止通过.call()/.apply()的方式非new调用,直接调用会抛出你遇到的'new' is required错误
  • 不会使用你传入的自定义this对象,必须由构造函数本身生成带合法内部槽的实例

这就是老写法失效的核心原因。

无class语法的正确实现(等价于class的super()逻辑)

ES6 class语法中super()的本质逻辑是:调用父类构造生成合法实例,同时将实例的原型绑定到当前子类的prototype,替换掉子类构造时默认生成的空this对象。不用class语法时,可通过Reflect.construct()实现完全一致的效果,这也是super()的底层实现逻辑:

// 第一步:正确设置原型链,修正constructor指向
MyClass.prototype = Object.create(Class.prototype, {
  constructor: {
    value: MyClass,
    enumerable: false,
    writable: true,
    configurable: true
  }
});

function MyClass() {
  // 等价于class语法中的 super(...arguments)
  // 第三个参数指定实例的原型绑定到当前调用的子类(支持子类继续继承MyClass的场景)
  const _this = Reflect.construct(Class, arguments, new.target || MyClass);

  // 子类自定义的属性、初始化逻辑全部挂载到_this上
  _this.customAttr = '子类自定义属性';

  // 必须返回_this,替换new MyClass时默认生成的空对象
  return _this;
}

// 原型方法可正常生效
MyClass.prototype.customMethod = function() {
  console.log(this.customAttr);
};

// 实例化验证
const myInstance = new MyClass(/* 传入父类构造需要的参数 */);
myInstance.customMethod(); // 正常输出
console.log(myInstance instanceof MyClass); // true
console.log(myInstance instanceof Class); // true
你之前尝试的new Class()方案的缺陷

你想到的手动new Class()后返回实例的写法,问题在于生成的实例原型固定指向Class.prototype,没有关联到MyClass.prototype,自然无法访问你在MyClass原型上定义的属性和方法。Reflect.construct的第三个参数就是专门用来指定实例原型对应的构造函数,刚好解决这个问题:生成的实例既带父类要求的所有内部合法槽位,原型链也完全符合继承预期。

注意:如果要兼容不存在ReflectAPI的极老运行环境(如IE11),没有方案可以完美继承这类ES6内置类。这类内置类的实例带有无法手动挂载的特殊内部槽,必须通过构造函数本身生成合法实例,这也是class语法成为ES6之后继承内置类标准方案的原因。

内容的提问来源于stack exchange,提问作者Sebastian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 18:57:18