//工具函数,判断所属类型,判断是不是null或者undefined const toString = Object.prototype.toString; const isType = obj => toString.call(obj).slice(8, -1).toLowerCase(); const isArray = obj => Array.isArray(obj) || isType(obj) === "array"; const isNullOrUndefined = obj => obj === null || obj === undefined; /** * 添加事件 * @param {*} type 监听事件的名称 * @param {*} fn 监听事件对应的方法 * @param {*} context 改变this的指向/执行的主体 * @param {*} once 是否只执行一次 */ const _addListener = function(type, fn, context, once) { if (typeof fn != "function") { throw new TypeError("fn 必须是一个函数"); } fn.context = context; fn.once = !!once; const event = this._events[type]; //若是只执行一次, this._events[type] 将是一次函数 if (isNullOrUndefined(event)) { this._events[type] = fn; } else if (typeof event === "function") { //若是已经存在(监听)一个函数,则this._events[type]将是一个数组 this._events[type] = [event, fn]; } else if (isArray(event)) { //若是存在(监听)多个函数(数组),则push this._events[type].push(fn); } return this; } //EventEmitter类 class EventEmitter { constructor() { //初始化_events属性 if (isNullOrUndefined(this._events)) { this._events = Object.create(null); } } //添加事件 addListener(type, fn, context) { return _addListener.call(this, type, fn, context); } //可执行屡次 on(type, fn, context) { return this.addListener(type, fn, context); } //执行一次 once(type, fn, context) { return _addListener.call(this, type, fn, context, true); } //事件触发 emit(type, ...rest) { if (isNullOrUndefined(type)) { throw new Error("emit必须接收至少一个参数"); } const events = this._events[type]; if (isNullOrUndefined(events)) return false; if (typeof events === "function") { //用call改变this的指向指向events.context主体,不然指向null events.call(events.context || null, rest); //执行完毕判断是否只执行一次,是则移除 if (events.once) { this.removeListener(type, events); } } else if (isArray(events)) { events.map(e => { e.call(e.context || null, rest); if (e.once) { this.removeListener(type, e); } }) } return true; } //事件移除 removeListener(type, fn) { if (isNullOrUndefined(this._events)) return this; if (isNullOrUndefined(type)) return this; if (typeof fn !== "function") { throw new Error("fn 必须是一个函数"); } const events = this._events[type]; if (typeof events === "function") { events === fn && delete this._events[type]; } else { const findIndex = events.findIndex(e => e === fn); if (findIndex === -1) return this; if (findIndex === 0) { events.shift(); } else { events.splice(findIndex, 1); } //若是只剩下一个监听者,则把数组变为函数 if (events.length === 1) { this._events[type] = events[0]; } } return this; } //删除全部事件 removeAllListeners(type) { if (isNullOrUndefined(this._events)) return this; //若是没有指定type,则删除所有 if (isNullOrUndefined(type)) this._events = Object.create(null); const events = this._events[type]; if (!isNullOrUndefined(events)) { //判断是否只剩下最后一个事件 if (Object.keys(this._events).length === 1) { this._events = Object.create(null); } else { delete this._events[type]; } } return this; } //监听队列 listeners(type) { if (isNullOrUndefined(this._events)) return []; const events = this._events[type]; return isNullOrUndefined(events) ? [] : (typeof events === "function" ? [events] : events.map(o => o)); } //监听者数量 listenerCount(type) { if (isNullOrUndefined(this._events)) return 0; const events = this._events[type]; return isNullOrUndefined(events) ? 0 : (typeof events === "function" ? 1 : events.length); } eventNames() { if (isNullOrUndefined(this._events)) return []; return Object.keys(this._events); } }
参考自https://www.php.cn/js-tutoria... 做者:php中世界最好的语言php