Set 和 Map 是 JavaScript 中语义清晰、性能高效的原生集合结构:Set 用于去重与快速成员判断,Map 支持任意类型键及插入顺序遍历;非必要场景(如简单字符串配置)仍应优先使用对象或数组。

Set 和 Map 是 JavaScript 中两种原生的集合数据结构,它们比传统的数组和对象在特定场景下更高效、更语义清晰。关键优势不在于“万能”,而在于“精准匹配需求”:当你需要去重、快速查存、或用非字符串键组织数据时,它们往往比手动模拟更可靠、更易读、更少出错。
Set:天然去重 + 快速成员判断
Set 用来存储唯一值(值本身即键),内部基于哈希实现,查找、插入、删除平均时间复杂度都是 O(1)。
- 替代 Array.filter + indexOf 去重:一行代码搞定,且保留原始顺序,不依赖 JSON.stringify 等脆弱方式
- 代替 includes 判断大量数据是否存在:对上百项以上的数组反复调用 includes 效率低;转成 Set 后用 has() 判断快得多
- 适合做交集、并集、差集运算:配合扩展运算符和 filter,逻辑清晰,比如 [...new Set(arr1)].filter(x => new Set(arr2).has(x)) 就是简单交集
Map:键可为任意类型 + 有序 + 可迭代
Map 的键可以是对象、函数、Symbol 甚至 null,且遍历时按插入顺序返回,这是普通对象做不到的。
- 缓存对象为键的数据:比如给 DOM 元素绑定私有元数据,map.set(element, { hovered: true }) 不污染 element 本身,也不怕 key 冲突
- 替代用 JSON.stringify 模拟对象键的对象字面量:避免序列化开销与精度丢失(如 NaN、undefined、函数无法被正确还原)
- 需要频繁增删键值对且关注插入顺序时:比如实现 LRU 缓存、状态机映射表、路由参数解析结果等
别硬套——什么时候不该用?
不是所有场景都适合。如果只是存几个固定字符串配置,普通对象更轻量;如果只做简单索引查找且键确定是字符串,对象或数组也完全够用。
立即学习“Java免费学习笔记(深入)”;
- 不需要去重?不用 Set:重复值有意义(如日志列表、计数中间态),就老实用数组
- 键全是字符串且不关心顺序?优先用对象:语法更简洁,JSON 序列化直接支持,工具链兼容性更好
- 只读查找、结构极简单、性能不敏感?不必强转 Map:过早优化反而增加认知负担
小技巧:轻松互转
它们和数组之间转换很自然,便于衔接现有逻辑:
- Array.from(set) 或 [...set] → 数组
- new Set(array) → 去重后的 Set
- new Map([[k1,v1],[k2,v2]]) 或 new Map(objEntries) → Map
- [...map] / [...map.keys()] / [...map.values()] → 展开为数组











