class Event { on(event, fn, ctx) { if (typeof fn !== 'function') { console.error('listener must be a function'); return; } this._stores = this._stores || {}; (this._stores[event] = this._stores[event] || []).push({ cb: fn, ctx: ctx }); } emit(event) { this._stores = this._stores || {}; let store = this._stores[event]; let args; if (store) { store = store.slice(0); args = [].slice.call(arguments, 1), args[0] = { eventCode: event, data: args[0] }; for (let i = 0, len = store.length; i < len; i++) { store[i].cb.apply(store[i].ctx, args); } } } off(event, fn) { this._stores = this._stores || {}; // all if (!arguments.length) { this._stores = {}; return; } // specific event const store = this._stores[event]; if (!store) return; // remove all handlers if (arguments.length === 1) { delete this._stores[event]; return; } // remove specific handler let cb; for (let i = 0, len = store.length; i < len; i++) { cb = store[i].cb; if (cb === fn) { store.splice(i, 1); break; } } return; } } module.exports = Event;