map是带键的有序哈希表,键可为任意类型且保留插入顺序;set是值的去重集合,无键概念、同样保序;object/array无法替代因键类型受限、遍历无序、原型风险等;高频写法包括链式set、对象作key缓存、set数组去重等。

直接画核心知识点思维导图,不用堆砌所有 API,重点抓本质区别和真实使用逻辑。下面这四块内容,就是你画图时最该放在中心辐射出去的主干分支。
Map 的本质:带键的有序哈希表
它不是“高级对象”,而是独立设计的键值结构:
- 键可以是任意类型(对象、函数、Symbol、null 都行),不强制转字符串
- 插入顺序严格保留,遍历时 keys() / values() / entries() 全部按添加顺序返回
- 底层用哈希表实现,查找、增删平均时间复杂度 O(1);元素过多时自动转红黑树防退化
- 判断键是否重复用 SameValueZero 算法(0 和 -0 相等,NaN 和 NaN 相等)
Set 的本质:只存值的去重集合
它不是“没有 key 的 Map”,而是一个值的唯一性容器:
- 内部也用哈希表实现,同样支持任意类型值(包括对象),靠 SameValueZero 判重
- 没有键的概念,只有值;add() 时若值已存在,静默忽略,不报错也不覆盖
- 遍历顺序也是插入顺序,forEach 或 for...of 都能拿到原始添加次序
- 天然适合做数组去重:
[...new Set(arr)]比filter((v, i) => arr.indexOf(v) === i)更简洁高效
为什么不能用 Object / Array 替代
这不是语法糖问题,而是能力边界问题:
- Object 的 key 只能是字符串或 Symbol → 无法用 {id: 1} 当缓存 key,所有对象都变成 "[object Object]"
- Object 遍历顺序不稳定 → 数字键升序排、字符串键按插入序,混合后顺序难预测,不适合做 FIFO 缓存
- Array 去重要手写逻辑 → filter + indexOf / includes 性能差,且无法处理对象元素的深比较
- Object 有原型链风险 → 用户输入 'toString' 或 '__proto__' 当 key,可能意外覆盖或触发原型方法
高频实用写法(导图右下角可加“速查区”)
把真正写业务时抄得最多的几行代码列出来,比背方法名有用得多:
- Map 初始化:
new Map([[k1,v1],[k2,v2]])或链式new Map().set(k1,v1).set(k2,v2) - 对象作 key 缓存:
const cache = new Map(); cache.set(componentInstance, data); - 数组去重(含对象):
[...new Set(items.map(JSON.stringify))].map(JSON.parse)(浅层对象适用) - 两个 Set 求差集:
new Set([...setA].filter(x => !setB.has(x)))) - 遍历 Map 写法最自然的是
for (const [key, value] of map),不是 forEach











