如何直接继承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
相关产品推荐
相关产品推荐

