对 d3.js 的事件调度感到困惑

Confused by d3.js's event dispatch

AFAICT 来自 docs 的 d3.js 事件,生成消耗[=33= 的所有代码部分] 这样的事件必须可以访问 d3.dispatch() 对象,该事件是 "declared"(因为缺少更好的词)。

这意味着这个 d3.dispatch 对象必须是全局可见的,即它必须保存在一个全局变量中。事实上,如果这个变量的范围再窄一些,那么事件的生成器 消费者都必须生活在同一范围内,这显然违背了事件驱动编程的目的,这是为了 完全解耦 代码部分(即 作用域 ),其中生成事件的部分与使用这些事件的部分相同。

该方案对共享 dispatch 对象的依赖对我来说毫无意义。如果 d3.dispatch() 返回的值始终是同一个对象,那会好一点(虽然,IMO,并不理想)。 AFAICT,以下测试表明情况并非如此(前导 >< 字符分别表示输入和输出):

> d3.dispatch() === d3.dispatch()
< false
> d3.dispatch( 'foo' )
< d3_dispatch {foo: function, on: function}
> d3.dispatch().foo()
VM10701:2 Uncaught TypeError: d3.dispatch(...).foo is not a function(anonymous function) @ VM10701:2InjectedScript._evaluateOn @ VM10514:883InjectedScript._evaluateAndWrap @ VM10514:816InjectedScript.evaluate @ VM10514:682

我是不是误会了什么?

如果你阅读代码,你会发现 d3.dispatch 是一个工厂函数,returns 一个新的 d3_dispatch 对象,它是一个添加了新的 d3_dispatch_event 对象的函数在它上面,对应于传递给 dispatch 工厂的参数。 d3_dispatch_event 工厂 returns 具有添加、服务和公开侦听器及其回调的方法的对象。它还在关联的侦听器数组上形成闭包,这对于每个事件都是唯一的。

所以,基本上,每个 dispatch 都是一个新对象,其行为继承自 d3_dispatch.prototyped3_dispatch_event.prototype,并且在 d3_dispatch_event 工厂中处于关闭状态。