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 面试官系列



