在 JavaScript 中,'Set'、'Map'、'WeakSet' 和 'WeakMap' 是 ES6 新增的集合类型,各有不同的用途和适用场景。以下是它们的用法和常见应用场景:
1. Set
特点:
- 存储唯一值(重复值会被自动去重)。
- 值可以是任意类型(原始类型或对象引用)。
- 可遍历(支持 'for...of'、'forEach' 等方法)。
常用方法:
- 'add(value)':添加值。
- 'has(value)':检查是否存在值。
- 'delete(value)':删除值。
- 'size':获取元素数量。
常见场景:
- 数组去重:快速去除数组中的重复项。
const arr = [1, 2, 2, 3];
const unique = [...new Set(arr)]; // [1, 2, 3]
- 记录唯一值:比如追踪用户已访问的页面。
- 集合操作:求交集、并集、差集(结合 'filter' 和 'has')。
2. Map
特点:
- 键值对集合,键可以是任意类型(对象、函数、原始类型等)。
- 保持键的插入顺序。
- 可遍历。
常用方法:
- 'set(key, value)':添加键值对。
- 'get(key)':获取值。
- 'has(key)':检查是否存在键。
- 'delete(key)':删除键值对。
- 'size':获取元素数量。
常见场景:
- 替代对象:当键需要非字符串类型时(如用对象作为键)。
const map = new Map();
const key = { id: 1 };
map.set(key, "data");
- 缓存数据:存储函数计算结果,避免重复计算。
- 关联元数据:将附加信息绑定到对象,但不想直接修改对象。
3. WeakSet
特点:
- 只能存储对象引用(不能是原始值)。
- 弱引用:如果对象在其他地方被垃圾回收,'WeakSet' 中的引用会自动移除。
- 不可遍历(没有 'size'、'keys()' 等方法)。
常用方法:
- 'add(obj)'
- 'has(obj)'
- 'delete(obj)'
常见场景:
- 临时对象追踪:比如跟踪一组需要处理的 DOM 元素,无需手动清理。
const weakSet = new WeakSet();
weakSet.add(document.getElementById('element'));
// 当元素从 DOM 移除后,weakSet 会自动释放其引用。
- 避免内存泄漏:适合管理对象生命周期相关的标记。
4. WeakMap
特点:
- 键必须是对象(值可以是任意类型)。
- 弱引用:键对象的回收会导致对应的键值对自动移除。
- 不可遍历(没有 'size'、'keys()' 等方法)。
常用方法:
- 'set(key, value)'
- 'get(key)'
- 'has(key)'
- 'delete(key)'
常见场景:
- 私有属性存储:为对象存储私有数据,避免污染对象本身。
const privateData = new WeakMap();
class MyClass {
constructor() {
privateData.set(this, { secret: 123 });
}
getSecret() {
return privateData.get(this).secret;
}
}
- DOM 节点元数据:关联数据与 DOM 元素,元素移除时自动清理数据。
const domData = new WeakMap();
const element = document.querySelector('#app');
domData.set(element, { clicks: 0 });
对比总结
| 类型 | 键/值类型 | 可遍历性 | 弱引用 | 垃圾回收友好 | 适用场景 |
|---|---|---|---|---|---|
| Set | 唯一值 | ✔️ | ❌ | ❌ | 去重、集合操作 |
| Map | 任意类型键值 | ✔️ | ❌ | ❌ | 复杂键、缓存、元数据 |
| WeakSet | 仅对象值 | ❌ | ✔️ | ✔️ | 临时对象追踪 |
| WeakMap | 仅对象键,任意值 | ❌ | ✔️ | ✔️ | 私有数据、DOM 关联数据 |
关键区别
- 弱引用:'WeakSet' 和 'WeakMap' 不会阻止垃圾回收,适合需要自动清理的场景。
- 性能:'Set'/'Map' 适合频繁操作和遍历;'Weak' 系列适合内存敏感的场景。
- 兼容性:所有现代浏览器均支持,但在旧环境(如 IE)需要 polyfill。
根据实际需求选择合适的数据结构,可以有效提升代码效率和内存管理!


被折叠的 条评论
为什么被折叠?



