Set / Map

1. 什么是 Set、Map

  • Set 是一种叫做集合的数据结构:是一堆无序的、相关联的,且不重复的元素组成的组合。
  • Map 是一种叫做字典的数据结构:是一些元素的集合,每个元素有一个称作 key 的域,不同元素的 key 各不相同。

2. Set 方法

Set 的遍历顺序就是插入顺序;可用于实现并集、交集、差集。

let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);

// 并集
let union = new Set([...a, ...b]);          // Set {1, 2, 3, 4}

// 交集
let intersect = new Set([...a].filter(x => b.has(x))); // Set {2, 3}

// (a 相对于 b 的) 差集
let difference = new Set([...a].filter(x => !b.has(x))); // Set {1}

常用方法:add、delete、has、clear、size、forEach。

3. Map 方法

Map 类型是键值对的有序列表,键和值都可以是任意类型,遍历顺序就是插入顺序。

常用方法:set、get、has、delete、clear、size、forEach,以及 keys() / values() / entries()。

4. WeakSet

WeakSet 可以接受一个具有 Iterable 接口的对象作为参数:

const a = [[1, 2], [3, 4]];
const ws = new WeakSet(a); // WeakSet {[1, 2], [3, 4]}

WeakSet 与 Set 的两个区别:

  • WeakSet 成员只能是引用类型,不能是其他类型的值。
let ws = new WeakSet();
let weakSet = new WeakSet([2, 3]); // 报错

let obj1 = { name: 1 };
let obj2 = { name: 1 };
let ws2 = new WeakSet([obj1, obj2]); // OK
  • WeakSet 里的引用只要在外部消失,它在 WeakSet 里的引用就会自动消失(不会屏蔽 GC)。

5. WeakMap

WeakMap 与 Map 的两个区别:

  • 键名必须是对象,且是弱引用;一旦键名所指向的对象不再需要,里面的键名对象和对应的键值对会自动消失,不用手动删除。
  • 注意:WeakMap 弱引用的只是键名,不是键值;键值仍是正常引用。
const wm = new WeakMap();
let key = {};
let obj = { foo: 1 };

wm.set(key, obj);
obj = null;
wm.get(key); // Object {foo: 1}  (键值 obj 仍被 wm 持有)

6. 弱引用

垃圾回收的规则:如果对象还有引用,就不会被回收。而弱引用不会屏蔽垃圾回收。

WeakSet 中的对象引用是弱引用,WeakMap 中的键也是弱引用(值不是)。当 WeakSet 中的项是某个对象的仅存引用时,它不会屏蔽垃圾回收。

补充:WeakSet/WeakMap 的常见用途是避免内存泄漏。例如给 DOM 节点附加元数据,节点被移除后无需手动清理;或者在大型对象库中作为"已访问"标记集合,对象不再被引用时自动释放。

来源整理自:vue3js.cn 面试官系列