【ES6(2015)】Set

在 JavaScript 里通常使用ArrayObject来存储数据。 在 ES6 中,新增了数据结构 SetMap,它们分别对应传统数据结构的“集合”和“字典”。首先,我们先来学习下 Set 数据结构。

ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

1. 基本语法

// 生成Set实例,可初始化为空
let s = new Set()
// 初始化的参数必须是可遍历的,可以是数组或者自定义遍历的数据结构。
let s = new Set([1, 2, 3, 4])

添加数据

s.add('hello')
s.add('goodbye')
// 也支持链式写法
s.add("hello").add('world')

Set 数据结构不允许数据重复,所以添加重复的数据是无效的(可以用来去重)

删除数据

// 删除指定数据
s.delete('hello') // true
// 删除全部数据
s.clear()

统计数据

// 判断是否包含数据项,返回 true 或 false
s.has('hello') // true
// 计算数据项总数
s.size // 2

数组去重

let arr = [1,2, 2, 3, 4, 2, 3, 1]
let s = new Set(arr)
console.log(s) // Set(4) {1, 2, 3, 4}

// 合并去重
let arr1 = [1, 2, 3, 4]
let arr2 = [2, 3, 4, 5, 6]
let s = new Set([...arr1, ...arr2])
console.log([...s])  // [1, 2, 3, 4, 5, 6]
console.log(Array.from(s))  // [1, 2, 3, 4, 5, 6]

交集

let s1 = new Set(arr1)
let s2 = new Set(arr2)
let result = new Set(arr1.filter(item => s2.has(item)))
console.log(Array.from(result))

差集

let arr3 = new Set(arr1.filter(item => !s2.has(item)))
let arr4 = new Set(arr2.filter(item => !s1.has(item)))
console.log(arr3)
console.log(arr4)
console.log([...arr3, ...arr4])

2. 遍历方式

  • keys():返回键名的遍历器
  • values():返回键值的遍历器
  • entries():返回键值对的遍历器
  • forEach():使用回调函数遍历每个成员
  • for...of:直接遍历每个成员
let s = new Set(['hello','world'])
s.forEach(item => {
    console.log(item) // hello // world
})

for (let item of s) {
    console.log(item)  // hello // world
}

for (let item of s.keys()) {
    console.log(item)  // hello // world
}

for (let item of s.values()) {
    console.log(item)  // hello // world
}

for (let item of s.entries()) {
    console.log(item[0], item[1])  // hello hello  // world world
}

3. WeakSet

WeakSet 结构与 Set 类似,也是不重复的值的集合。但是,它与 Set 有两个区别。

  • WeakSet 的成员只能是对象,而不能是其他类型的值;
  • WeakSet 没有size属性,没有办法遍历它的成员

WeakSet 有三个方法:add, delete, has

const ws = new WeakSet()
ws.add(1)
// TypeError: Invalid value used in weak set
ws.add(Symbol())
// TypeError: invalid value used in weak set
let ws = new WeakSet()
const obj1 = {
    name: 'imooc'
}
const obj2 = {
    age: 5
}
ws.add(obj1)
ws.add(obj2)
ws.delete(obj1)
console.log(ws) 
console.log(ws.has(obj2)) // true

WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中。

那么它有啥作用呢?

  • 避免内存泄露(用于存储DOM节点,而不用担心这些节点从文档移除时会引发内存泄露)
const foos = new WeakSet()
class Foo {
	constructor() {
		foos.add(this)
	}
	method() {
		if(!foos.has(this)) {
			throw new TypeError("Foo.prototype..method 只能在Foo的实例上调用")
		}
	}
}
// 这段代码的作用是保证了Foo 的实例方法只能在Foo的实例上调用。
// 这里用WeakSet的好处:数组foos对实例的引用不会被计入内存回收机制,所以删除实例时无需考虑foos, 也不会出现内存泄露
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

优小U

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值