Map和Set是ES6为弥补对象与数组缺陷而设计的原生集合类型,语义准确、行为稳定、性能可预期:Map支持任意类型键且保持插入顺序,size为O(1);Set去重与存在性判断均为O(1),适合高频更新场景。
Map 和 Set 是 ES6 引入的原生集合类型,不是语法糖,而是为解决对象和数组在特定场景下的硬伤而设计的。它们强不在“功能多”,而在“语义准、行为稳、性能可预期”。
普通对象本质是属性容器,不是数据结构。Map 才是专为键值映射设计的工具:
{id: 1}、undefined、数字 42)自动转成字符串,导致 {id: 1} 和 {name: 'a'} 都变成 "[object Object]",键冲突;Map 允许任意值作键,且只对同一引用判等。
串和 Symbol 键;Map 对所有键类型都保证顺序,遍历 for (const [k, v] of map) 总是稳定可靠。map.size 是 O(1);对象得靠 Object.keys(obj).length,每次都要生成新数组。频繁增删时,Map 底层哈希实现比对象属性动态分配更轻量。用数组模拟集合,本质是“用线性结构扛哈希需求”,容易掉坑:
filter((v, i) => arr.indexOf(v) === i) 或嵌套循环,时间复杂度 O(n²);Set 构造时就去重:new Set([1, 1, 2]) 直接得 {1, 2},O(n) 一次过。arr.includes(id) 是 O(n);Set 用 set.has(id) 是平均 O(1),尤其在几千个元素以上差距明显。push/splice 会改变索引,Set 的 add/delete 不涉及位移,适合高频更新的集合(如实时在线用户列表、已读消息 ID 缓存)。不是所有场景都适合上 Map/Set:
{ theme: 'dark', lang: 'zh' }),对象更简洁,可直接解构、点访问、JSON 序列化。arr[100000] = 'x'),数组仍是唯一选择;Set 和 Map 不支持下标寻址。真正体现优势的,是那些“数据动态变化+需高频查找+键类型复杂”的场景——比如用 DOM 元素作键缓存计算结果(Map)、用用户 ID 实时维护已选状态(Set)。这时候,不是“能用”,而是“该用”。(资料截至 2025 年 12 月)