一文读懂 JS 中的 Set 结构

你好,我是沐爸,欢迎点赞、收藏、评论和关注。

今天聊下 Set 数据结构,看下它如何使用?和 Map 有什么区别?有哪些属性和方法?又有哪些使用场景?WeakMap 又是什么?下面直接进入正题。

一、Set 和 Map 有什么区别?

  • Set 是一个集合,类似于数组,但是成员的值都是唯一的,不能重复。主要用于快速查找、去重等场景。
  • Map 是一组键值对的集合,其中每个元素都是一个键值对。与普通的对象不同,Map 的键不仅限于字符串,也可以是任意类型(如对象或函数)。

二、WeakSet 和 Set 的区别?

WeakSet 结构与 Set 类似,也是不重复的值的集合。两者的区别在于:

  • WeakSet 的成员只能是对象和 Symbol 值,而不能是其他类型的值。
  • WeakSet 对象不计入垃圾回收机制。
  • Set 可遍历,WeakSet 不可遍历。

三、Set 实例有哪些属性和方法?

1.属性

  • constructor:构造函数,默认就是 Set 函数
  • size:返回 Set 实例的成员总数

2.方法

  • 操作方法
    • add(value) 添加某个值,返回 Set 实例本身
    • delete(value) 删除某个值,返回一个布尔值,表示删除是否成功
    • has(value) 查询该值是否是 Set 实例的成员,返回一个布尔值
    • clear() 清除所有成员,没有返回值
  • 遍历方法:
    • keys() 返回键名的遍历器
    • values() 返回键值的遍历器
    • entries() 返回键值对的遍历器
    • forEach() 使用回调函数遍历每个成员
  • 集合运算方法:
    • intersection(other) 交集
    • union(other) 并集
    • difference(other) 差集
    • symmetricDifference(other):对称差集
    • isSubsetOf(other):判断是否为子集
    • isSupersetOf(other):判断是否为超集
    • isDisjointFrom(other):判断是否不相交
javascript 复制代码
// 示例1
let s1 = new Set()
s1.add(1)
s1.add(2)
s1.add(3)
s1.add(4)
s1.size // 4
s1.has(1) // true
s1.has(5) // false
s1.delete(5) // false
s1.delete(1) // true
s1.clear()

// 示例2
let s2 = new Set(['red', 'green', 'blue'])

for (let item of s2) console.log(item)
for (let item of s2.keys()) console.log(item)
for (let item of s2.values()) console.log(item)
s2.forEach(item => console.log(item))
// 四种遍历结果相同,依次打印 red、green、blue

for (let item of s2.entries()) console.log(item)
// ['red', 'red']
// ['green', 'green']
// ['blue', 'blue']

// 示例3
let s3 = new Set(['a', 'b', 'c', 'd'])
let s4 = new Set(['c', 'd', 'e', 'f'])
let s5 = new Set(['a', 'b'])

s3.union(s4) // ['a', 'b', 'c', 'd', 'e', 'f'] 并集
s3.intersection(s4) // ['c', 'd'] 交集
s3.difference(s4) // ['a', 'b'] 差集
s3.symmetricDifference(s4) // ['a', 'b', 'c', 'd', 'e', 'f'] 对称差集 = 并集 - 交集
s3.isSubsetOf(s4) // false s3不是s4的子集
s5.isSubsetOf(s3) // true s5是s3的子集
s3.isSupersetOf(s5) // true s3是s5的超集
s4.isDisjointFrom(s5) // s4与s5不相交

四、Set 的使用场景有哪些?

1.数组去重

javascript 复制代码
const set = new Set([1, 2, 3, 4, 4])
[...set] // [1,2,3,4]

2.字符串去除重复字符

javascript 复制代码
[...new Set('ababbc')].join('')
// "abc"

3.集合运算

求两个数组之间的并集、交集、差集等,上面已有示例。

五、WeakSet 如何使用?

  • 成员只能是对象或 Symbol,不能是其他数据类型的值
  • 有3个方法:add、delete、has,用法同 Set
  • 没有 size 属性,不支持遍历,for/forEach/keys()/values()/entries()都不能用
javascript 复制代码
const ws = new WeakSet()

ws.add(1) // 报错
ws.add(Symbol()) // 不报错

const a = [[1, 2], [3, 4]]
const ws = new WeakSet(a)
// WeakSet {[1, 2], [3, 4]}

const b = [3, 4];
const ws = new WeakSet(b);
// Uncaught TypeError: Invalid value used in weak set(...)

ws.size // undefined
ws.forEach // undefined

六、WeakSet 的使用场景?

  1. 内存管理 :当你需要跟踪一组对象但不希望阻止这些对象被垃圾回收时,WeakSet 是个好选择。它帮助避免内存泄漏,因为它不会阻止成员对象被自动回收。
  2. 私有成员管理 :在面向对象编程中,WeakSet 可用于存储类的私有成员或状态,同时保持对内存使用的控制。
  3. 缓存失效 :当缓存或映射依赖于对象存在时,使用 WeakSet 可以确保当对象被垃圾回收时,相关的缓存或映射也自动失效,减少内存浪费。
  4. DOM元素管理 :在处理DOM元素时,WeakSet 可用于跟踪一组特定的元素,而无需担心因保留引用而阻止元素被垃圾回收。

好了,分享结束,谢谢点赞,下期再见。

相关推荐
Boilermaker19926 分钟前
【Java EE】SpringIoC
前端·数据库·spring
中微子17 分钟前
JavaScript 防抖与节流:从原理到实践的完整指南
前端·javascript
天天向上102432 分钟前
Vue 配置打包后可编辑的变量
前端·javascript·vue.js
芬兰y1 小时前
VUE 带有搜索功能的穿梭框(简单demo)
前端·javascript·vue.js
好果不榨汁1 小时前
qiankun 路由选择不同模式如何书写不同的配置
前端·vue.js
小蜜蜂dry1 小时前
Fetch 笔记
前端·javascript
拾光拾趣录1 小时前
列表分页中的快速翻页竞态问题
前端·javascript
小old弟1 小时前
vue3,你看setup设计详解,也是个人才
前端
Lefan1 小时前
一文了解什么是Dart
前端·flutter·dart
Patrick_Wilson1 小时前
青苔漫染待客迟
前端·设计模式·架构