Map和Set是解决键值映射与自动去重问题的专用工具:Map支持对象作键、插入顺序遍历、O(1)查存;Set提供O(1)去重与存在性判断;小规模静态场景仍宜用对象和数组。
Map 和 Set 不是“比对象和数组强”,而是解决不同问题的专用工具——当你需要键值映射且键可能是对象、或需要自动去重+快速查存时,它们就是更安全、更快、更少出错的选择。
Map 替代对象做键值映射:为什么 obj[{}] 总是失效?普通对象把所有键强制转成字符串,{id: 1} 和 {id: 2} 都变成 "[object Object]",结果互相覆盖。Map 没这问题,它认的是引用本身。
const userMap = new Map();
const user1 = { id: 1 };
const user2 = { id: 2 };
userMap.set(user1, "Alice");
userMap.set(user2, "Bob");
console.log(userMap.get(user1)); // "Alice"
obj[{}] = "Alice" → 实际是 obj["[object Object]"] = "Alice",第二次赋值就覆盖了for (const [key, val] of map) 严格按插入顺序;对象的 for...in 在数字键上会升序排列,不可靠map.size;对象得写 Object.keys(obj).length,还可能误算原型链上的属性Set 替代数组去重:别再写 filter((v, i) => arr.indexOf(v) === i)
数组去重本质是 O(n²) 查找,10 万条数据时卡顿明显;Set 底层哈希实现,插入/判断存在性都是平均 O(1)。
const uniqueIds = [...new Set([1, 2, 2, 3, 3])]; // [1, 2, 3]
set.has(x) 比 arr.includes(x) 或 arr.indexOf(x) > -1 快一个数量级(尤其大数据量)Set 用 SameValueZero 规则判等,所以 NaN === NaN 成立,而数组 indexOf(NaN) 返回 -1set[0] 是 undefined,要转数组才可索引:[...set][0]
它们不是银弹。小规模、静态、结构简单时,对象和数组反而更直观、更轻量。
立即学习“Java免费学习笔记(深入)”;
const config = { timeout: 5000, retries: 3
} 更自然arr.push() / arr.splice() 语义清晰JSON.stringify() 不认 Map/Set,得手动转:Object.fromEntries(map) 或 [...set]
WeakMap / WeakSet,它们不能遍历,但内存更友好真正容易被忽略的点是:Map/Set 的「语义明确性」——当你写出 new Map(),别人立刻知道这是动态键值关系;写出 new Set(),就知道这个集合必须唯一。这种意图表达,比任何注释都可靠。