JavaScript中无内置事件总线,可通过Pub-Sub模式手动实现EventBus类,含on、emit、off方法;需注意内存泄漏,避免匿名订阅,并在组件卸载时清理;大型项目优先选用状态管理或Context。

JavaScript 中没有内置的跨组件事件总线(Event Bus),但可以通过一个简单的发布-订阅(Pub-Sub)模式手动实现,核心是维护一个事件监听器集合,并提供 on(订阅)、emit(触发)、off(取消订阅)方法。
用一个空对象模拟事件中心
创建一个独立的事件总线实例,不依赖任何框架,纯 JS 即可运行:
class EventBus {
constructor() {
this.events = {};
}
on(event, callback) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(callback);
}
emit(event, ...args) {
const callbacks = this.events[event];
if (callbacks && callbacks.length) {
callbacks.forEach(cb => cb(...args));
}
}
off(event, callback) {
const callbacks = this.events[event];
if (callbacks) {
this.events[event] = callbacks.filter(cb => cb !== callback);
}
}
}
// 使用示例
const bus = new EventBus();
// 组件 A 订阅
bus.on('user-login', (user) => {
console.log('欢迎回来:', user.name);
});
// 组件 B 触发
bus.emit('user-login', { name: '张三' });
避免内存泄漏:记得取消订阅
在组件卸载或销毁时,若未清理监听器,会导致回调函数持续驻留内存,尤其在单页应用中容易引发性能问题。
- 推荐在订阅时保存回调引用,便于后续精确移除
- 不要用匿名函数订阅,否则无法通过
off清理 - Vue/React 等框架中,通常在
beforeUnmount或useEffect cleanup里调用off
支持通配符和事件继承(进阶可选)
如果需要更灵活的匹配(比如监听所有以 data- 开头的事件),可在 on 和 emit 中加入简单模式匹配逻辑:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- 用
event.includes(':')支持类似form:submit的命名空间 - 用
event.startsWith('api:')批量响应一类事件 - 也可扩展
once方法,让监听器只执行一次
现代替代方案:优先考虑状态管理或 Context
事件总线虽轻量,但在大型项目中易导致逻辑分散、调试困难。实际开发中建议:
- 小模块通信(如弹窗与表单)可用 EventBus 快速解耦
- 父子/兄弟组件通信,优先用 props / 自定义事件 / Context / Pinia / Zustand
- 全局状态变更(如登录态、主题切换),更适合用响应式状态库统一管理
不复杂但容易忽略细节:关键是保持事件名语义清晰、订阅生命周期可控、避免过度依赖广播式通信。

















