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

如何直接继承EventTarget对象?解决非法构造函数报错及内存问题

如何正确继承EventTarget避免"Illegal constructor"错误

你遇到的问题在早期浏览器环境里确实很常见——当时EventTarget的构造函数不允许通过extends直接继承,不过现在现代浏览器已经支持标准的继承方式了,同时也有兼容旧环境的方案,不用再去继承Document浪费内存啦!

一、现代浏览器的直接继承方案

现在Chrome、Firefox、Edge等现代浏览器已经完全支持直接继承EventTarget,你的初始代码其实在这些环境里是可以正常运行的,可能你之前测试的环境比较旧?再试一下这段代码:

class OwnClass extends EventTarget {
  constructor() {
    super();
    // 这里可以添加你的自定义初始化逻辑
  }
}

// 测试事件功能
function eventHandler() {
  console.log("自定义事件触发啦!", arguments);
}

let et = new OwnClass();
et.addEventListener("Own Event", eventHandler);
et.dispatchEvent(new Event("Own Event"));

这段代码会正常打印事件触发的信息,完全不需要依赖Document这种重量级对象。

二、兼容旧环境的方案(组合替代继承)

如果需要兼容一些不支持直接继承EventTarget的旧环境,推荐用组合模式:内部创建一个EventTarget实例,然后代理它的事件方法,这样既实现了事件监听能力,又不会有多余的内存开销:

class OwnClass {
  constructor() {
    // 内部维护一个EventTarget实例
    this._eventTarget = new EventTarget();
  }

  // 代理addEventListener方法
  addEventListener(type, listener, options) {
    return this._eventTarget.addEventListener(type, listener, options);
  }

  // 代理removeEventListener方法
  removeEventListener(type, listener, options) {
    return this._eventTarget.removeEventListener(type, listener, options);
  }

  // 代理dispatchEvent方法
  dispatchEvent(event) {
    return this._eventTarget.dispatchEvent(event);
  }
}

// 同样可以正常测试
function eventHandler() {
  console.log("自定义事件触发啦!", arguments);
}

let et = new OwnClass();
et.addEventListener("Own Event", eventHandler);
et.dispatchEvent(new Event("Own Event"));

为什么不要继承Document?

Document是整个DOM文档的根节点对象,它包含了大量DOM相关的属性和方法,实例化它会占用很多不必要的内存,而且完全偏离了你只需要事件监听能力的需求,所以这种方案一定要避免。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:37:44