面试 3 分钟,Map vs Set 答成“一个有 key 一个没有”?
今天用 5 个真实代码片段,让你把区别 + 场景一次说清。
一、核心区别 10 秒速记
| 维度 | Map | Set |
|---|---|---|
| 用途 | 键值对存储 | 唯一值集合 |
| 键类型 | 任意类型(对象、NaN、Symbol…) | 只能是值本身 |
| 重复判断 | 键唯一 | 值唯一 |
| 迭代顺序 | 插入顺序 | 插入顺序 |
| API 差异 | .get(key) / .set(key,val) | .add(val) / .has(val) |
二、实战 5 连击
① 前端缓存:Map 存对象键值
// 缓存接口结果,用对象当 key
const cache = new Map();
function fetchUser(id) {
if (cache.has(id)) return Promise.resolve(cache.get(id));
return axios.get(`/user/${id}`).then(res => {
cache.set(id, res.data);
return res.data;
});
}
② 去重数组:Set 一行搞定
const uniqueTags = [...new Set(rawTags)];
③ 计数器:Map 统计词频
const counter = new Map();
for (const word of words) {
counter.set(word, (counter.get(word) || 0) + 1);
}
④ 权限白名单:Set 快速判断
const whiteList = new Set(['admin', 'editor']);
function canEdit(role) {
return whiteList.has(role);
}
⑤ 双向映射:Map + Set 组合
// 用户 ↔ 标签 双向查询
const userTags = new Map(); // userId → Set<tag>
const tagUsers = new Map(); // tag → Set<userId>
function addTag(userId, tag) {
if (!userTags.has(userId)) userTags.set(userId, new Set());
userTags.get(userId).add(tag);
if (!tagUsers.has(tag)) tagUsers.set(tag, new Set());
tagUsers.get(tag).add(userId);
}
三、易错点提醒
| 误区 | 正确姿势 |
|---|---|
用 {} 当缓存键 | 用 Map,避免原型链污染 |
数组去重 indexOf | 用 Set,O(n) → O(1) |
频繁 includes 查找 | 换成 Set.has,性能提升 10× |
四、一句话总结(面试速背)
“Map 是万能键值表,Set 是高性能唯一集合;缓存、去重、计数、白名单,记住这四个场景就能拿满分。”