JavaScript 中 Map 和 WeakMap 的比较
Map 和 WeakMap 都是 JavaScript 中的键值对集合,但它们有一些重要的区别:
Map (映射)
特点:
- 键可以是任意类型(对象、原始值等)
- 保持对键的强引用,防止键被垃圾回收
- 可遍历(可以使用
keys(),values(),entries()等方法) - 可以获取大小(通过
size属性) - 键是唯一的(使用 SameValueZero 算法比较)
使用场景:
- 需要存储任意类型键值对
- 需要遍历或获取集合大小
- 键需要长期存在不被回收
示例:
const map = new Map();
const key = { id: 1 };
map.set(key, 'value');
console.log(map.get(key)); // 'value'
console.log(map.size); // 1
// 遍历
for (const [k, v] of map) {
console.log(k, v);
}
WeakMap (弱映射)
特点:
- 键必须是对象或非全局注册的符号(Symbol)(不能是原始值)
- 对键保持弱引用,不影响垃圾回收
- 不可遍历(没有迭代方法)
- 无法获取大小(没有
size属性) - 键是唯一的(使用对象引用比较)
使用场景:
- 需要以对象为键且不希望影响垃圾回收
- 存储对象的私有或元数据
- 不需要遍历或知道集合大小
示例:
const weakMap = new WeakMap();
const key = { id: 1 };
weakMap.set(key, 'private data');
console.log(weakMap.get(key)); // 'private data'
// 当 key 被垃圾回收后,weakMap 中的条目会自动移除
主要区别总结
| 特性 | Map | WeakMap |
|---|---|---|
| 键类型 | 任意类型 | 必须是对象 |
| 键引用 | 强引用 | 弱引用 |
| 可遍历 | 是 | 否 |
| 可获取大小 | 是 (size 属性) | 否 |
| 垃圾回收影响 | 防止键被回收 | 不阻止键被回收 |
| 性能 | 相对较低 | 相对较高 |
| 使用场景 | 通用键值存储 | 对象关联元数据 |
何时使用
-
使用 Map 当:
- 需要遍历键值对
- 需要知道集合大小
- 键可以是原始值
- 需要长期保持键值对
-
使用 WeakMap 当:
- 只需要用对象作为键
- 不希望影响垃圾回收
- 不需要遍历或知道大小
- 存储与对象关联的临时数据
WeakMap 特别适合用于实现私有属性、缓存系统或任何与对象生命周期绑定的数据存储场景。