Set、Map、WeakSet、WeakMap 知识点总结及对比
1. Set(集合)
- 定义:存储 唯一值 的集合(值可以是任意类型)。
- 特性:
- 值不可重复(重复值自动去重)。
- 有序存储(按插入顺序)。
- 方法:
add(value)
:添加值。delete(value)
:删除值。has(value)
:检查是否存在值。clear()
:清空集合。size
:获取元素数量。
- 遍历方法:
keys()
、values()
、entries()
、forEach()
。
- 应用场景:
- 数组去重:
[...new Set(array)]
。 - 记录唯一操作(如防止重复提交)。
- 数组去重:
- 示例:
const set = new Set(); set.add(1).add(2).add(1); // 自动去重 console.log(set.size); // 2 console.log([...set]); // [1, 2]
2. Map(映射)
- 定义:存储 键值对 的集合,键可以是任意类型(对象、函数等)。
- 特性:
- 键唯一(重复键覆盖旧值)。
- 有序存储(按插入顺序)。
- 方法:
set(key, value)
:设置键值对。get(key)
:获取值。has(key)
:检查是否存在键。delete(key)
:删除键值对。clear()
:清空映射。size
:获取键值对数量。
- 遍历方法:
keys()
、values()
、entries()
、forEach()
。
- 应用场景:
- 存储对象关联的元数据。
- 替代普通对象(当键需要非字符串类型时)。
- 示例:
const map = new Map(); const key = { id: 1 }; map.set(key, "Alice").set("age", 20); console.log(map.get(key)); // "Alice" console.log([...map.entries()]); // [[{id:1}, "Alice"], ["age", 20]]
3. WeakSet(弱集合)
- 定义:存储 唯一对象 的弱引用集合。
- 特性:
- 只能存储对象(不能是原始值)。
- 弱引用:不计入垃圾回收机制,对象无其他引用时会被自动回收。
- 不可遍历(无
size
、keys()
等方法)。
- 方法:
add(obj)
:添加对象。delete(obj)
:删除对象。has(obj)
:检查是否存在对象。
- 应用场景:
- 临时跟踪对象(如标记已处理的对象)。
- 避免内存泄漏(自动回收无引用的对象)。
- 示例:
const weakSet = new WeakSet(); let obj = { data: "test" }; weakSet.add(obj); console.log(weakSet.has(obj)); // true obj = null; // 后续可能被垃圾回收,weakSet 自动移除该对象
4. WeakMap(弱映射)
- 定义:存储 键值对 的弱引用映射,键必须是对象。
- 特性:
- 键是弱引用(不计入垃圾回收机制)。
- 不可遍历(无
size
、keys()
等方法)。 - 值可以是任意类型。
- 方法:
set(key, value)
:设置键值对。get(key)
:获取值。has(key)
:检查是否存在键。delete(key)
:删除键值对。
- 应用场景:
- 存储对象的私有数据(避免污染对象本身)。
- 缓存对象关联的数据(自动回收无引用的键)。
- 示例:
const weakMap = new WeakMap(); let key = { id: 1 }; weakMap.set(key, "Private Data"); console.log(weakMap.get(key)); // "Private Data" key = null; // 后续可能被垃圾回收,weakMap 自动移除该键值对
5. 核心对比
特性 | Set | Map | WeakSet | WeakMap |
---|---|---|---|---|
键/值类型 | 值(任意类型) | 键(任意类型)、值(任意类型) | 值(必须是对象) | 键(必须是对象)、值(任意类型) |
可遍历性 | 支持(forEach 、for...of ) | 支持(forEach 、for...of ) | 不支持 | 不支持 |
引用类型 | 强引用 | 强引用 | 弱引用(键) | 弱引用(键) |
垃圾回收影响 | 不自动回收 | 不自动回收 | 自动回收无引用的对象 | 自动回收无引用的键 |
使用场景 | 去重、集合操作 | 键值对存储、复杂键类型 | 临时对象标记 | 私有数据、缓存 |
6. 常见问题
-
Set 和数组有何区别?
- Set 自动去重且无序(按插入顺序存储),数组允许重复且有序。
-
Map 和普通对象有何区别?
- Map 的键可以是任意类型,普通对象的键只能是字符串或 Symbol。
-
WeakSet/WeakMap 为什么不能遍历?
- 弱引用设计导致无法保证元素稳定性,垃圾回收可能随时移除元素。
-
如何选择 Set 和 WeakSet?
- 若需长期持有对象引用,使用 Set;若需自动管理对象生命周期,使用 WeakSet。
总结
- Set/Map:适合常规数据存储,支持遍历和复杂操作。
- WeakSet/WeakMap:专为弱引用场景设计,避免内存泄漏,适合临时数据关联。
- 优先使用场景:
- 唯一值集合 →
Set
。 - 键值对存储 →
Map
。 - 对象临时标记 →
WeakSet
。 - 对象私有数据 →
WeakMap
。
- 唯一值集合 →