← 返回目录

10. Set 和 Map

两个新集合类型:Set"自动去重的袋子"——你往里扔重复的东西它只留一个,专门解决去重;Map"钥匙随便的柜子"——普通对象的钥匙只能是字符串,Map 的钥匙数字、对象、数组都能当。

10.1 互动演示

点按钮看 Set / Map 的实际行为。

10.2 知识点讲解

一、Set:自动去重的袋子

① 以前去重要写循环,现在一行

以前去重得写一个空数组,遍历原数组,每看到一个新值才 push 进去——啰嗦。new Set(数组) 自动去重,再用 [...] 展开回数组,一行搞定。

let arr = [1, 2, 3, 4, 4, 3]; // 有重复的数组

// 以前:循环 + indexOf 判断,啰嗦
let unique = [];              // 先开个空数组
arr.forEach(x => {           // 挨个遍历
  if (unique.indexOf(x) === -1) unique.push(x); // 没见过才加
});

// 现在:new Set 自动去重 + ... 展开回数组
let unique = [...new Set(arr)]; // Set 自动去重,... 再拆回数组
//     ^^^ 把 Set 重新拆成数组
console.log(unique); // [1,2,3,4]

new Set(数组) 自动去重,[...set] 再变回数组。这是最常用的数组去重写法,面试必背

② Set 常用方法

往袋子里扔(add)、拿出来看有没有(has)、扔掉一个(delete)、倒空(clear)、数个数(size)。

let s = new Set();       // 开个空袋子
s.add("大哥"); // 扔进去
s.add("二哥");            // 再扔一个
s.add("大哥"); // 重复的扔不进去,袋子自动忽略
s.size; // 2(袋子里现在有几个)
s.has("大哥"); // true(有没有这个)
s.delete("二哥"); // 扔掉一个 → true
s.clear(); // 整个袋子倒空

二、Map:钥匙随便的"加强版对象"

③ 普通对象的键会被转成字符串

普通对象有个坏习惯:你拿数字当钥匙,它偷偷帮你转成字符串;想拿对象当钥匙?门都没有。Map 不转类型,钥匙原样保留。

// 普通对象:键强制转字符串
let obj = {};            // 普通对象
obj[123] = "数字键";     // 拿数字 123 当键
console.log(obj); // {"123": "数字键"} ← 123 被转成 "123" 了

// Map:键保持原样,对象也能当键
let m = new Map();       // 开个 Map
m.set(123, "数字键"); // 数字键
m.set({ id: 1 }, "对象键"); // 对象当键,普通对象做不到!
console.log(m.get(123)); // 数字键

Map 的键可以是数字、对象、数组,不会像普通对象那样被强制转成字符串。动态增删键值对、需要用对象/数字当 key 的场景,用 Map 最合适。

④ Map 常用方法

let m = new Map();       // 开个空 Map
m.set("name", "大喇叭"); // 放一对键值
m.get("name"); // 拿值 → 大喇叭
m.has("name"); // 有没有 → true
m.delete("name"); // 删掉一对 → true
m.size; // 有几对
m.clear(); // 全清空

⑤ 普通对象 vs Map

对比项普通对象Map
键的类型只能字符串 / 符号任意类型(数字、对象都行)
遍历for...in 比较绕forEach 直接遍历,按插入顺序
常用场景字段固定的数据(如 User)动态增删的键值对

10.3 实战:用在哪 / 常见坑 / 怎么解决

① 可能在什么地方用:数组去重 [...new Set(arr)]、两个数组求交集/并集、用对象当 key 存关联数据、记录用户访问过的页面。

② 常见的问题:把 Set 当数组直接用 arr[i] 取下标(Set 没有下标);用普通对象存对象键导致 key 全变字符串;遍历 Map 用 for...in 遍历不到。

③ 解决思路:Set 要取下标就先 [...set] 展开;Map 用 m.forEachfor...of m;需要对象键就用 Map,别用普通对象。

一句话:Set 管"不重复",Map 管"任意键";去重用 [...new Set(arr)]