ECMAScript 6 Set与WeakSet详解:用法、去重及内存管理
本文详细解析ES6引入的Set和WeakSet数据结构。Set用于存储唯一值,支持遍历、转换数组及高效去重;WeakSet仅存储对象且为弱引用,无size属性且不可遍历,主要用于存储DOM节点以避免内存泄漏。文章涵盖API用法、常见陷阱及最佳实践。
ES6 Set数据结构基础
ES6引入了一个新的数据结构Set,其特性与Java中的Set类似,主要作用是存储不重复的元素。Set是一个类,使用时需要通过new关键字实例化。
var s1 = new Set()
s1.add(1)
s1.add(2)
s1.add(3)
s1.add(1)
var s2 = new Set()
s2.add('a')
s2.add('a')
// 输出1,2, 3
for (var i of s1 ) {
console.log(i)
}
// 输出a
for (var i of s2 ) {
console.log(i)
}
使用Set的add方法添加元素时,如果尝试添加已存在的重复值,该值不会被存入Set中。
Set的构造函数还可以接收一个数组作为参数进行初始化。
var s3 = new Set([1,2,3,1])
s3.size // 3
即使传入包含重复数字1的数组,Set中仍只保留一个1。获取Set的元素数量应使用size属性,而非length。
需要注意的是,对于对象{}或数组[],即使内容相同,它们也是两个不同的对象,因此Set会将它们视为不同的元素存储。
var s4 = new Set()
s4.add({})
s4.add({})
s4.size // 2
Set的遍历与数组转换
一、遍历Set(for...of)
var s1 = new Set()
s1.add(1)
s1.add(2)
s1.add(3)
// 输出1,2, 3
for (var i of s1) {
console.log(i)
}
二、将Set转换为数组
var s1 = new Set()
s1.add(1)
s1.add(2)
// toArray
var a1 = Array.from(s1)
Array.isArray(a1) // true
// or
var a1 = [...new Set(s1)]
三、利用Set实现数组去重
function distinct(arr) {
return Array.from(new Set(arr))
// return [...new Set(arr)]
}
例如:

Set的属性
constructor size Set的方法
has(val) 判断元素是否存在 add(val) 添加元素 delete(val) 删除指定元素 clear 清空所有元素 keys values entries forEach 遍历元素 map filter
WeakSet特性与应用场景
四、WeakSet
WeakSet与Set类似,都不存储重复元素,但存在显著差异。
1. WeakSet只能存储对象类型的元素。
ws = new WeakSet()
ws.add(1)
在Firefox浏览器中尝试添加非对象类型会报错,如下所示。

2. WeakSet仅提供add、delete、clear和has四个方法,不支持遍历操作,也没有size属性。
ws = new WeakSet()
ws.size // undefined
ws.forEach // undefined
MDN官方解释如下:
WeakSet对象中存储的对象值都是被弱引用的。如果没有其他变量或属性引用这个对象值,则该对象值会被垃圾回收机制自动回收。正因如此,WeakSet对象无法被枚举,也无法获取其包含的所有元素列表。
WeakSet的主要应用场景是存储DOM节点。当这些节点从文档中被移除时,WeakSet不会持有强引用,从而避免引发内存泄漏。
以上内容即为本文的全部讲解,希望对大家有所帮助。
JS语法错误会阻止加载吗?区分SyntaxError与资源加载失败
2026-11-05 16:08:46
JavaScript常见SyntaxError语法错误排查与修复方法
2026-11-05 13:58:44
JS中slice、substring和substr截取字符串的区别
2026-11-05 13:43:47
JS 转 TS 手动迁移最佳实践:从配置 tsconfig 到消除 any 类型
2026-11-05 11:53:32
为什么JS数组push后得到的是数字而不是数组?
2026-11-05 09:59:18
