Event,EventTarget,EventEmitter
EventTarget
這裡說明瀏覽器中的
EventTarget
DOM 節點的事件操作(監聽和觸發),都定義在
EventTarget
介面。所有節點物件
都部署了(實現)這個介面,其他一些需要事件通訊的瀏覽器內建物件(比如,XMLHttpRequest
、AudioNode
、AudioContext
)也部署了(實現)這個介面。
事件通常由
外部源
觸發,同樣也會以程式設計方式
觸發,例如執行一個 element 的一個 HTMLElement.click( ) 方法,或透過定義事件
,然後使用 EventTarget.dispatchEvent( ) 將其派發到一個指定的目標。
該介面主要提供三個例項方法:
addEventListener()
:繫結事件的監聽函式removeEventListener()
:移除事件的監聽函式dispatchEvent()
:觸發事件
Event
事件發生以後,會產生一個事件物件,作為引數傳給監聽函式。瀏覽器原生提供一個
Event
物件,所有的事件都是這個物件的例項,或者說繼承了Event.prototype
物件。
Event
物件本身就是一個建構函式,可以用來生成新的例項。
EventEmitter
在
Node.js
的events
模組中,EventEmitter
是一個非常重要的類,很多模組都繼承了它,比如Stream
、HTTP
、Net
等。
EventEmitter
的使用非常簡單,它提供了on
、once
、emit
、removeListener
等方法,用於註冊事件監聽器、觸發事件、移除事件監聽器等。
Node中的 EventTarget和Event
Node.js 中的
EventTarget
和Event
物件是對EventTarget
Web API 的特定實現。
瀏覽器的EventTarget和node中EventEmitter 區別
Node.js 和瀏覽器都是基於事件驅動的平臺,而 EventEmitter 和 EventTarget 分別是它們的核心事件處理機制。
區別
EventEmitter
和EventTarget
都是用來實現事件的,但是它們之間還是有一些區別的。
首先,
EventTarget
會有事件冒泡,而EventEmitter
沒有事件冒泡。
因為在nodejs
中是不存在層級關係的,所有的模組都是平級的,所以EventEmitter
也就沒有事件冒泡。
而在瀏覽器中,DOM
元素天然就有層級關係,事件冒泡也就是自然而然的事情了,如果沒有事件冒泡,那麼事件的傳遞就會變得非常麻煩。
其次就是
EventEmitter
和EventTarget
的實現方式不同;
EventEmitter
是一個釋出訂閱模式的實現,而EventTarget
是一個觀察者模式的實現。這兩種模式的區別在於,釋出訂閱模式中,釋出者和訂閱者是沒有關係的,釋出者只負責釋出事件,訂閱者只負責訂閱事件,釋出者和訂閱者之間沒有任何關係。
而觀察者模式中,觀察者和被觀察者是有關係的,觀察者會觀察被觀察者的變化,當被觀察者發生變化時,觀察者會收到通知。
這也是為什麼
EventEmitter
中事件觸發是可以直接透過字串,而EventTarget
中事件觸發需要透過事件物件的原因。同時也是因為這個原因他們的
API
也有所不同,EventEmitter
中會有once
這種只執行一次就移除的方法,而EventTarget
中沒有這種方法。
在
nodejs
的events
模組中,其實也有EventTarget
的實現,但是它並不是繼承EventEmitter
的,而是改寫了EventEmitter
的實現,使其符合EventTarget
的規範。他們的區別同樣也是沒有事件冒泡,同時執行環境不同,服務的物件也不同。
總結
EventEmitter
和EventTarget
都是用來實現事件的,但是它們之間還是有一些區別的。最大的區別就是一個是
node
環境,一個是瀏覽器環境,為了服務不同的環境,它們的實現方式也不同。
EventEmitter
是一個釋出訂閱模式的實現,而EventTarget
是一個觀察者模式的實現。
EventEmitter
中事件觸發是可以直接透過字串,而EventTarget
中事件觸發需要透過事件物件。
參考:
Node.js中的EventEmitter與瀏覽器中的EventTarget:深度探索事件處理的異同
前端事件Event以及EventTarget
瀏覽器的 EventTarget 介面,Event 物件以及原生事件
EventTarget 介面
Event 物件
深入探討:Node.js中的EventEmitter與瀏覽器
Nodejs-Events模組