Литература описывает то, что доступно к использованию разработчикам сайтов. Такие вещи как DOM являются частью браузера и написаны с использованием низкоуровневого кода и внутренних возможностей, которые не предоставляют разработчикам по различным причинам. Вполне вероятно, что событийная модель у DOM-элементов тоже написана с использованием внутренних средств. Хотя реализовать этот паттерн на чистом JavaScript'е не представляет из себя ничего сложного:
class Element {
constructor() {
this._events = {};
}
addEventListener(event, listener) {
let listeners = this._events[event];
if (!listeners) {
listeners = this._events[event] = [];
}
listeners.push(listener);
}
removeEventListener(event, listener) {
const listeners = this._events[event];
if (listeners) {
const index = listeners.indexOf(listener);
if (index !== -1) {
listeners.splice(index, 1);
}
}
}
dispatchEvent(event) {
const listeners = this._events[event];
if (listeners) {
for (let listener of listeners) {
listener(event);
}
}
}
}
С помощью Map можно и вовсе избавиться от псевдоприватного свойства _events и хранить его ассоциативно.