Map和Set是ES6引入的原生集合类型:Map支持任意类型键、保留插入顺序、无原型污染;Set专注唯一值去重与存在性判断,性能优于数组。
Map 和 Set 是 ES6 引入的两种原生数据结构,不是语法糖,而是为解决传统对象和数组在特定场景下的短板而设计的真正集合类型。
Map:适合需要“任意类型键”的键值对场景
普通对象只接受字符串或 Symb
ol 作键,而 Map 允许用对象、函数、数字甚至 NaN 当键——关键在于“引用相等”而非“值相等”。比如缓存 DOM 节点对应的状态、给某个配置对象绑定元数据,都天然适合用 Map。
- 键可以是任何类型,包括 {id: 1}、document.body、NaN
- 插入顺序严格保留,遍历时按添加顺序返回
- map.size 直接获取长度,不用 Object.keys(obj).length
- 没有原型污染风险,map.has('toString') 不会误判继承来的属性
- 频繁增删键值对时性能更稳定(尤其键是动态生成的对象)
Set:专注“唯一值”的存在性与去重操作
Set 就是一个只存值、不存键的集合,自动去重,内部用哈希实现,has() 查找是 O(1),比数组 includes() 或 indexOf() 快得多。
- 初始化可直接传数组:new Set([1,2,2,3]) → {1,2,3}
- 快速判断是否存在:set.has(x),比数组遍历直观又高效
- 一行去重:[...new Set(arr)] 或 Array.from(new Set(arr))
- 支持基础集合运算(交、并、差),配合展开运算符就能写清楚逻辑
- 适合管理标签、权限列表、已读 ID、临时标记等“只需知道有没有”的场景
别用错:什么时候不该优先选它们?
如果只是静态配置,键固定且全是字符串,比如 {theme: 'dark', lang: 'zh'},普通对象更轻量、可序列化、IDE 支持更好。Map 没有字面量语法,不能直接 JSON.stringify(需手动转)。Set 也不适合需要索引访问或保持原始顺序但允许重复的场景——那还是该用数组。
WeakMap / WeakSet 是它们的弱引用版本,只接收对象键/值,适合做私有状态或避免内存泄漏,但不能遍历,也不适用于通用存储。
基本上就这些。








