简体   繁体   English

哪个对象“持有” addEventListener?

[英]Which object “holds” addEventListener?

For reasons, I'm looking for the source object that defines addEventListener . 由于某些原因,我正在寻找定义addEventListener的源对象。 Starting from XMLHttpRequest , I've discovered the following: XMLHttpRequest开始,我发现了以下内容:

> Object.prototype.hasOwnProperty(XMLHttpRequest.prototype, 'addEventListener')
false

> XMLHttpRequest.prototype.__proto__
XMLHttpRequestEventTarget {}

> Object.prototype.hasOwnProperty(XMLHttpRequestEventTarget.prototype, 'addEventListener')
false

> XMLHttpRequestEventTarget.prototype.__proto__
EventTarget {}

> Object.prototype.hasOwnProperty(EventTarget.prototype, 'addEventListener')
false

> EventTarget.prototype.__proto__
Object {}

How is it possible? 这怎么可能? addEventListener doesn't seem to be defined in any prototype. 在任何原型中似乎都没有定义addEventListener

To be clear, I know that this function is a native function, but what I don't understand is how, from a standard point of view, the property isn't available from any prototype but still there when we need it. 明确地说,我知道此函数是一个本机函数,但是我不了解的是,从标准的角度来看,该属性如何无法从任何原型中获得,但是在需要时仍然存在。

DOM interfaces are complicated. DOM 接口很复杂。 They are specified as an interface ( EventTarget in this case), but the methods have to be implemented on each "class" or prototype separately because JS doesn't have multiple inheritance or interfaces. 它们被指定为接口(在这种情况下为EventTarget ),但是由于JS没有多个继承或接口,因此必须分别在每个“类”或原型上实现方法。 The exact inheritance hierarachy may vary between browsers and their versions though. 但是,确切的继承层次结构可能在浏览器及其版本之间有所不同。

In your example, addEventListener is actually implemented on the XMLHttpRequest prototype (at least in my Opera), only you were checking it wrong: 在您的示例中, addEventListener实际上是在XMLHttpRequest原型上实现的(至少在我的Opera中是这样),只有您检查错了:

// Opera 12
XMLHttpRequest.prototype.hasOwnProperty("addEventListener") // true
Object.prototype.hasOwnProperty.call(XMLHttpRequest.prototype,  "addEventListener") // true
//                              ^^^^
Object.prototype.isPrototypeOf(XMLHttpRequest.prototype) // true - flat hierarchy

// Chrome 48
EventTarget.prototype.hasOwnProperty("addEventListener") // true
XMLHttpRequest.prototype instanceof EventTarget // true - some indirection

EventTarget prototype holding that property: 拥有该属性的EventTarget原型:

console.log(EventTarget.prototype.hasOwnProperty('addEventListener'))
// true

Take o look on Mozilla MDN: EventTarget.addEventListener() 看一下Mozilla MDN:EventTarget.addEventListener()

The EventTarget.addEventListener() method registers the specified listener on the EventTarget it's called on. EventTarget.addEventListener()方法在调用它的EventTarget上注册指定的侦听器。

From Mozilla MDN: EventTarget Mozilla MDN:EventTarget

EventTarget is an interface implemented by objects that can receive events and may have listeners for them. EventTarget是由对象实现的接口,这些对象可以接收事件并可能具有侦听器。

Element , document , and window are the most common event targets, but other objects can be event targets too, for example XMLHttpRequest, AudioNode, AudioContext, and others. Elementdocumentwindow是最常见的事件目标,但是其他对象也可以是事件目标,例如XMLHttpRequest,AudioNode,AudioContext等。

Methods 方法

EventTarget.addEventListener() Register an event handler of a specific event type on the EventTarget. EventTarget.addEventListener()在EventTarget上注册特定事件类型的事件处理程序。 .......... .......... ..................

So addEventListener could be called on all interfaces which inherits properties from EventTarget interface( window , document , Element etc.). 因此,可以在所有继承自EventTarget接口( 窗口文档元素等)的属性的接口上调用addEventListener。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM