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

如何实现继承EventTarget的静态单例类,支持事件监听与触发?

解决方案

首先明确你两种写法报错的原因:

  • 第一种写法:MyClass.dispatchEvent不存在,因为EventTarget的核心方法是实例方法,挂载在EventTarget.prototype上,而MyClass作为构造函数本身并没有继承这些实例方法。
  • 第二种写法:MyClass.prototype只是普通对象,并非EventTarget实例,不符合dispatchEvent对调用上下文的接口要求,因此报错。

要实现「通过构造函数和原型引入EventTarget方法、同时保证单例」的需求,核心思路是让类本身成为EventTarget实例,而非让类的实例继承EventTarget。具体实现如下:

class MyClass extends EventTarget {
  // 禁止实例化,确保单例特性
  constructor() {
    throw new Error('MyClass 是单例类,请直接使用静态方法');
  }

  // 自定义静态分发方法
  static dispatch(type) {
    // this指向MyClass本身,此时它已经是EventTarget实例
    this.dispatchEvent(new Event(type));
  }
}

// 修改类的原型链,让MyClass本身继承EventTarget实例的所有方法
Object.setPrototypeOf(MyClass, new EventTarget());

// 使用示例
MyClass.addEventListener('hello', () => {
  console.log('hello 事件已触发');
});

MyClass.dispatch('hello'); // 输出: hello 事件已触发

逻辑说明

  1. 原型链修改:Object.setPrototypeOf(MyClass, new EventTarget()) 让MyClass这个构造函数对象直接继承EventTarget实例的方法,因此MyClass本身就具备addEventListener、dispatchEvent、removeEventListener等核心能力。
  2. 单例保障:构造函数抛出错误,彻底阻止意外实例化的可能,避免多实例导致的事件逻辑混乱。
  3. 原生方法复用:无需额外定义静态变量存储实例转发方法,直接通过原型链复用EventTarget的原生实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 07:30:59