我正在尝试(也许是徒劳的)提出一种使用发布-订阅模式的方法,而 a)不使用任何库的 b)最小化使用它的模块中的样板代码。到目前为止,我想出的最好的办法是:

var handle = document.createElement();
var unsubscribe = AwesomeModule.subscribe(handle);

handle.addEventListener('awesome', function() {
    console.log('awesome');
});

这会很好地工作,除了使用AwesomeModule的人可能会因必须提供一个不用作元素的随机DOM元素而感到困惑。

我尝试了以下方法,但效果不太好:
var handle = Object.create(EventTarget);
var unsubscribe = AwesomeModule.subscribe(handle);

handle.addEventListener('awesome', function(){
    console.log('awesome')
});

我得到TypeError: Object [object Object] has no method 'addEventListener'。有趣的是,即使句柄将EventTarget作为其原型(prototype),它似乎也没有出现在原型(prototype)链中。

为什么不起作用?有没有一种方法可以用纯JS实现EventTarget?可以用单行代码完成它,而不会惊吓AwesomeModule的用户吗?

编辑:我不知道为什么昨晚我没想到它,但是我认为EventTarget是一个接口(interface),意味着它没有实现代码。令人困惑的是,在Chrome调试器控制台中,Object.create(EventTarget)将一个看起来带有addEventListener的对象作为原型(prototype)链。也许它说谎。谁能解释这种行为?谁能解释为什么W3选择不将EventTarget设置为具体的“类”?

最佳答案

看来我的原始问题的答案是"is"。由于JavaScript没有像Java这样的继承模型,它不会对合法实现进行编译时检查,因此我想任何Object都可以仅通过使用具有相同名称的方法来实现接口(interface)。但是,这样做将构成一个库,因为addEventListener代码未在EventTarget中实现(我之前已经假设是)。由于似乎没有跨浏览器的方法来获取普通的EventTarget,因此我可能会结合使用window.addEventListener和自定义事件。

07-24 14:53