双语面试:实现一个事件发布/订阅函数

29 阅读1分钟

面试题 Interview Question

实现一个简单的 EventEmitter 函数,支持 onoffemit 方法。
Implement a simple EventEmitter function that supports on, off, and emit methods.


要求 Requirements

  1. on(event, callback) 注册事件处理函数
    on(event, callback) registers a listener for the given event
  2. emit(event, ...args) 触发某个事件,并将参数传递给对应的处理函数
    emit(event, ...args) triggers the event and passes arguments to the listener(s)
  3. off(event, callback) 移除特定事件的某个处理函数
    off(event, callback) removes a specific listener for the given event
  4. 使用纯函数式风格,避免使用 this(可用闭包代替类)
    Use a functional style where possible; avoid using this (use closures instead of class if needed)

参考答案 Reference Solution

function createEmitter() {
  const events = new Map();

  return {
    on(event, callback) {
      const list = events.get(event) || [];
      events.set(event, [...list, callback]);
    },
    emit(event, ...args) {
      (events.get(event) || []).forEach(fn => fn(...args));
    },
    off(event, callback) {
      const list = events.get(event) || [];
      events.set(event, list.filter(fn => fn !== callback));
    }
  };
}

示例 Example

const emitter = createEmitter();

function greet(name) {
  console.log(`Hello, ${name}!`);
}

emitter.on('hello', greet);
emitter.emit('hello', 'Alice'); // 输出 Output: Hello, Alice!

emitter.off('hello', greet);
emitter.emit('hello', 'Bob');   // 无输出 No output

面试考察点 Interview Focus

  • 对发布/订阅模式(pub-sub)的理解
    Understanding of publish/subscribe pattern
  • 数据结构的选择与操作能力(如 Map、数组去重)
    Ability to use and manage data structures (e.g., Map, array filtering)
  • 对闭包与作用域链的掌握
    Mastery of closures and scope chains