JavaScript Set与WeakSet高效去重实战指南
在前端开发中,数据去重是处理数组、对象集合的高频需求。传统去重(如双重循环、indexOf)代码冗余且性能有限,ES6引入的Set与WeakSet为去重提供了更优雅、高效的解决方案。本文将深入解析两者的去重原理与实战场景,帮你快速掌握前端去重新范式。
一、Set:基础型集合的去重利器
Set是ES6新增的无序集合,其核心特性是元素唯一(基于“严格相等”判断,NaN视为相同,对象引用不同则视为不同元素)。利用这一特性,Set天生适合解决“重复元素过滤”问题。
1. 数组去重的极简实现
传统数组去重需嵌套循环或借助indexOf,而Set只需一行代码:
const arr = [1, 2, 2, 'a', 'a', NaN, NaN];
const uniqueArr = [...new Set(arr)]; // 输出: [1, 2, "a", NaN]
原理:Set会自动过滤重复元素,再通过扩展运算符(或Array.from())将Set转回数组,完成去重。
2. 字符串、类数组的去重
Set同样支持字符串、类数组等可迭代对象的去重。例如,过滤字符串中的重复字符:
const str = "aabbbcc";
const uniqueStr = [...new Set(str)].join(''); // 输出: "abc"
3. 复杂场景:对象引用去重
若数组元素为对象,Set会根据引用地址判断唯一性。例如:
const objArr = [{id:1}, {id:1}, {id:2}];
const uniqueObjArr = [...new Set(objArr)];
// 输出仍为3个元素,因为对象引用不同
若需基于对象属性去重(如根据id),可结合Map或reduce,但Set的“引用相等”特性更适合纯对象引用去重场景。
二、WeakSet:弱引用集合的特殊去重
WeakSet是Set的“弱引用”版本,仅支持对象类型作为元素,且对元素的引用不影响垃圾回收(即若对象无其他强引用,WeakSet中的引用会被自动释放)。
1. 适用场景:临时对象的去重管理
- DOM元素去重:若需跟踪“已处理的DOM节点”,使用
WeakSet存储节点引用,当节点从DOM树移除且无其他引用时,WeakSet中的引用会自动失效,避免内存泄漏。const weakSet = new WeakSet(); function processNode(node) { if (weakSet.has(node)) return; // 已处理则跳过 weakSet.add(node); // 标记为已处理 // 执行DOM操作... } - 临时对象池:若需对“临时创建的对象”去重(如函数内的缓存对象),
WeakSet可避免因强引用导致的内存无法回收。
2. 限制与特性
- 仅存储对象,无法存储原始类型(如数字、字符串);
- 不可迭代(无
forEach、for...of支持),无size属性,仅暴露add、delete、has方法; - 弱引用特性使其更适合“临时对象管理”,而非需要持久化的去重场景。
三、Set与WeakSet的去重场景对比
| 特性 | Set | WeakSet |
|---|---|---|
| 元素类型 | 支持所有类型(原始+对象) | 仅支持对象 |
| 引用类型 | 强引用(影响垃圾回收) | 弱引用(不影响垃圾回收) |
| 可迭代性 | 支持(for...of、forEach) |
不可迭代 |
| 去重场景 | 数组、字符串等通用去重 | DOM元素、临时对象的去重管理 |
| 性能 | 高频查询/迭代场景更优 | 内存敏感的临时对象场景更优 |
实战:混合场景的去重优化
需求:对“包含原始值和对象”的数组去重,且需管理临时对象的内存。
方案:用Set处理原始值+对象引用去重,用WeakSet管理临时对象的生命周期:
const mixedArr = [1, 2, 2, {id:1}, {id:1}, {id:2}];
// 1. 原始值+对象引用去重(Set)
const uniqueBySet = [...new Set(mixedArr)];
// 2. 临时对象内存管理(WeakSet)
const tempWeakSet = new WeakSet();
function cleanTempObjects(objList) {
objList.forEach(obj => {
if (tempWeakSet.has(obj)) return;
tempWeakSet.add(obj);
// 处理临时对象...
});
}
四、总结:选对工具,高效去重
- 若需通用型去重(如数组、字符串、数字集合),优先使用
Set,其简洁的API和可迭代性可大幅提升开发效率; - 若需临时对象的去重管理(如DOM节点、函数内缓存对象),且关注内存回收,
WeakSet是更安全的选择; - 避免混淆两者的适用场景:
Set适合“持久化去重”,WeakSet适合“临时性去重+内存优化”。
通过Set与WeakSet的灵活运用,你可以告别繁琐的传统去重逻辑,用更简洁、高效的代码解决前端数据去重问题。掌握这两个工具,让你的代码既优雅又具备性能优势。
文章版权声明:除非注明,否则均为Dark零点博客原创文章,转载或复制请以超链接形式并注明出处。

