class EventEmitter { constructor() { this._events = {} } on(eventName, cb) { if (!this._events[eventName]) { this._events[eventName] = [] } this._events[eventName].push(cb) } emit(eventName, ...args) { const callbacks = this._events[eventName] || [] callbacks.forEach(cb => { if (typeof cb === 'function') { cb.apply(null, args) } }) } once(eventName, cb) { const onceCb = (...args) => { cb.apply(null, args) this.off(eventName, cb) } this.on(eventName, onceCb) } off(eventName, cb) { const cbs = this._events[eventName] || [] const newCbs = cbs.filter(callback => cb !== callback) this._events[eventName] = newCbs }}