一文读懂 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 可用于跟踪一组特定的元素,而无需担心因保留引用而阻止元素被垃圾回收。

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

相关推荐
无心使然云中漫步17 分钟前
GIS OGC之WMTS地图服务,通过Capabilities XML描述文档,获取matrixIds,origin,计算resolutions
前端·javascript
Bug缔造者23 分钟前
Element-ui el-table 全局表格排序
前端·javascript·vue.js
xnian_1 小时前
解决ruoyi-vue-pro-master框架引入报错,启动报错问题
前端·javascript·vue.js
麒麟而非淇淋2 小时前
AJAX 入门 day1
前端·javascript·ajax
2401_858120532 小时前
深入理解MATLAB中的事件处理机制
前端·javascript·matlab
阿树梢2 小时前
【Vue】VueRouter路由
前端·javascript·vue.js
随笔写3 小时前
vue使用关于speak-tss插件的详细介绍
前端·javascript·vue.js
史努比.3 小时前
redis群集三种模式:主从复制、哨兵、集群
前端·bootstrap·html
快乐牌刀片884 小时前
web - JavaScript
开发语言·前端·javascript
秋雨凉人心4 小时前
call,apply,bind在实际工作中可以使用的场景
javascript