JavaScript中的Map、WeakMap、Set、WeakSet详解
字数 1212 2025-11-21 12:53:27
JavaScript中的Map、WeakMap、Set、WeakSet详解
描述
Map、WeakMap、Set、WeakSet是ES6引入的四种集合类型,用于存储数据集合。它们与传统对象和数组相比,具有更专用的特性和内存管理机制。理解它们的区别和使用场景对于编写高效、无内存泄漏的JavaScript代码至关重要。
知识详解
1. Map(映射)
- 基本特性:键值对集合,键可以是任意类型(对象、函数、基本类型等)。
- 与Object的区别:
- Object的键只能是字符串或Symbol,Map的键可以是任意值。
- Map维护键的插入顺序,Object不保证顺序。
- Map可直接迭代,Object需要先获取键数组。
- Map大小通过
size属性直接获取,Object需要手动计算。
- 常用方法:
set(key, value):添加键值对。get(key):获取键对应的值。has(key):检查键是否存在。delete(key):删除键值对。clear():清空集合。
- 示例:
const map = new Map(); const keyObj = { id: 1 }; map.set(keyObj, "Value associated with object"); map.set(42, "Answer to everything"); console.log(map.get(keyObj)); // "Value associated with object" console.log(map.size); // 2
2. Set(集合)
- 基本特性:存储唯一值的集合,值可以是任意类型。
- 与Array的区别:
- Set自动去重,Array需要手动处理。
- Set的元素访问需要通过迭代或
has()方法,Array可直接通过索引访问。
- 常用方法:
add(value):添加值。has(value):检查值是否存在。delete(value):删除值。clear():清空集合。
- 示例:
const set = new Set(); set.add(1); set.add(2); set.add(1); // 重复值被忽略 console.log(set.size); // 2 console.log(set.has(2)); // true
3. WeakMap(弱映射)
- 基本特性:键必须是对象,键是弱引用(不阻止垃圾回收)。
- 与Map的区别:
- 键必须是对象,不能是基本类型。
- 不可迭代(无
keys()、values()、entries()方法)。 - 无
size属性和clear()方法。
- 使用场景:存储对象的私有数据或元数据,避免内存泄漏。
- 示例:
let obj = { name: "Alice" }; const weakMap = new WeakMap(); weakMap.set(obj, "Private data"); console.log(weakMap.get(obj)); // "Private data" obj = null; // 当obj被垃圾回收时,WeakMap中的键值对自动移除
4. WeakSet(弱集合)
- 基本特性:值必须是对象,值是弱引用。
- 与Set的区别:
- 值必须是对象。
- 不可迭代,无
size属性。
- 使用场景:标记对象(如检查对象是否已处理过),无需担心内存泄漏。
- 示例:
let obj1 = { id: 1 }; let obj2 = { id: 2 }; const weakSet = new WeakSet(); weakSet.add(obj1); weakSet.add(obj2); console.log(weakSet.has(obj1)); // true obj1 = null; // obj1被垃圾回收后,WeakSet中自动移除
关键知识点总结
- 强引用与弱引用:Map和Set持有强引用,阻止垃圾回收;WeakMap和WeakMap持有弱引用,不阻止垃圾回收。
- 内存管理:使用WeakMap/WeakSet可避免因集合引用导致的对象无法回收。
- 迭代能力:Map/Set可直接迭代,WeakMap/WeakSet不可迭代。
- 使用选择:
- 需要键值对且键类型多样 → Map。
- 需要存储唯一值 → Set。
- 需要关联对象与数据且避免内存泄漏 → WeakMap。
- 需要标记对象且自动管理内存 → WeakSet。
通过理解这些集合类型的特性,可以在不同场景下选择最合适的结构,提升代码的效率和健壮性。