Map 适合管理路由表和状态机,因其键支持任意类型且查找为 O(1);路由可用 URL/正则/函数作键,状态机可用 [状态, 事件] 数组或 Symbol 作键,避免字符串拼接与引用相等陷阱。

用 Map 管理路由表或状态机,核心是利用其键的灵活性(支持任意类型)和 O(1) 查找性能,比普通对象更安全、更语义清晰。
用 Map 存储路由处理器
相比字符串键的对象,Map 可以直接用 URL 对象、正则、甚至自定义路由类作键,避免字符串拼接和类型转换错误。
示例:按路径前缀匹配的简易路由表
const router = new Map();
// 键可以是字符串(基础)、正则(动态)、函数(条件路由)
router.set('/home', () => console.log('首页'));
router.set(/^\/user\/(\d+)$/, (match) => console.log('用户详情:', match[1]));
router.set('/about', () => console.log('关于页'));
function handleRoute(path) {
// 先尝试精确匹配
const exactHandler = router.get(path);
if (exactHandler) return exactHandler();
// 再遍历检查正则键
for (const [key, handler] of router.entries()) {
if (key instanceof RegExp && key.test(path)) {
return handler(key.exec(path));
}
}
console.log('404');
}
handleRoute('/user/123'); // 输出:用户详情: 123
用 Map 实现状态机转移表
状态机中,“当前状态 + 输入事件 → 下一状态 + 动作” 的映射天然适合 Map。可将复合键(如 [state, event])作为键,避免嵌套对象或字符串拼接。
推荐做法:用 Symbol 或数组作为键,保证唯一性和可读性
const STATE = { IDLE: Symbol('IDLE'), LOADING: Symbol('LOADING'), SUCCESS: Symbol('SUCCESS'), ERROR: Symbol('ERROR') };
const EVENT = { CLICK: 'click', SUBMIT: 'submit', RESOLVE: 'resolve', REJECT: 'reject' };
// 转移表:键为 [状态, 事件] 数组,值为 { next, action }
const stateTransitions = new Map();
stateTransitions.set([STATE.IDLE, EVENT.CLICK], {
next: STATE.LOADING,
action: () => console.log('开始加载...')
});
stateTransitions.set([STATE.LOADING, EVENT.RESOLVE], {
next: STATE.SUCCESS,
action: () => console.log('加载成功')
});
stateTransitions.set([STATE.LOADING, EVENT.REJECT], {
next: STATE.ERROR,
action: () => console.log('加载失败')
});
function transition(currentState, event) {
const entry = stateTransitions.get([currentState, event]);
if (!entry) return currentState; // 无定义转移,保持原状态
entry.action?.();
return entry.next;
}
let state = STATE.IDLE;
state = transition(state, EVENT.CLICK); // 开始加载... → LOADING
state = transition(state, EVENT.RESOLVE); // 加载成功 → SUCCESS
增强可维护性的技巧
实际项目中,建议封装一层 API,隐藏 Map 细节,提供声明式注册和类型提示:
- 用
router.on(path, handler)替代裸set(),内部自动处理正则/字符串归一化 - 状态机可导出预定义的
TRANSITIONS常量对象,再批量导入到Map - 搭配 TypeScript 使用时,给
Map显式标注泛型,如Map<string routehandler></string>或Map,提升类型安全 - 调试时可用
Array.from(map.entries())快速查看所有映射关系
注意边界情况
Map 的键是引用相等(===),不是值相等。所以不要用每次新建的对象/数组当键:
// ❌ 错误:两次 new Array() 是不同引用,查不到 map.set(['a'], 'value'); console.log(map.get(['a'])); // undefined // ✅ 正确:复用同一数组,或改用字符串键 / JSON.stringify() const key = ['a']; map.set(key, 'value'); console.log(map.get(key)); // 'value'
对动态路径或事件组合,优先用字符串键(如 `${state}-${event}`)或 Symbol,更稳定可控。



















