```js // 请使用原生代码实现一个Events模块,可以实现自定义事件的订阅、触发、移除功能 const fn1 = (... args)=>console.log('I want sleep1', ... args) const fn2 = (... args)=>console.log('I want sleep2', ... args) const event = new Events(); event.on('sleep', fn1, 1, 2, 3); event.on('sleep', fn2, 1, 2, 3); event.fire('sleep', 4, 5, 6); // I want sleep1 1 2 3 4 5 6 // I want sleep2 1 2 3 4 5 6 event.off('sleep', fn1); event.once('sleep', () => console.log('I want sleep')); event.fire('sleep'); // I want sleep2 1 2 3 // I want sleep event.fire('sleep'); // I want sleep2 1 2 3 ``` 今天的题目算是一道常考题了,没有一个标准解法,输出正确就行。 但是如果你能用上一些 ES6 的语法以及处理好一些边界问题,面试官对你的评价会更好点。 ```js class Events { constructor() { this.events = new Map(); } addEvent(key, fn, isOnce, ...args) { const value = this.events.get(key) ? this.events.get(key) : this.events.set(key, new Map()).get(key) value.set(fn, (...args1) => { fn(...args, ...args1) isOnce && this.off(key, fn) }) } on(key, fn, ...args) { if (!fn) { console.error(`没有传入回调函数`); return } this.addEvent(key, fn, false, ...args) } fire(key, ...args) { if (!this.events.get(key)) { console.warn(`没有 ${key} 事件`); return; } for (let [, cb] of this.events.get(key).entries()) { cb(...args); } } off(key, fn) { if (this.events.get(key)) { this.events.get(key).delete(fn); } } once(key, fn, ...args) { this.addEvent(key, fn, true, ...args) } } ```