ClarenceC/JavaScript-ES6Plus-Learn

Set

Opened this issue · 0 comments

在ES6以前,js里面只支持 Array 数组,数据保存成数组都是以 Array 形式,在 ES6后,多了两类类型 Set 和 Map。

Set

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

const s = new Set()
[2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x))

for (let i of s) { //能用 for ...of 遍历 set 数组。
  console.log(i)
}
  1. Set 结构里面添加成员,是通过 add() 方法向里面添加的,并且 Set 结构不会添加重复的值。

  2. Set 函数可以接受一个数组作为参数新建对象。

const set = new Set([1, 2, 3, 4, 4])
[...set] // [1, 2, 3, 4]
set.size //  4
const set = new Set(document.querySelectorAll('div'))
  1. Set 数据数组长度是通过 set.size 来获取,和 Array.length 不一样。

  2. 可以通过 Set 数据类型进行数组去重。

[...new Set(array)] 

[...new Set('abaccc')].join('') // 'abc'
  1. 加入 Set 数据类型内部的值,不会发生类型转换。

Set 实例的属性和方法

其实 Set 是一个构造函数,

  • Set.prototype.constructor: 构造函数,指回 Set 函数。
  • Set.prototype.size: 返回 Set 实例的成员总数。

Set 实例的方法分为两大类

  1. 操作方法(用于操作数据)
  • add(value): 添加值到 Set 数组里面。
  • delete(value): 删除某个值,返回Boolean值,表示删除是否成功。
  • has(value): 返回一个布尔 值,表示该值是否为 Set 的成员。
  • clear(): 清除所有成员,没有返回值。
  1. Set 可以通过 Array.from 把数据转为数组。
const items = new Set(['a', 4, 78])
const array = Array.from(new Set(array))
  1. 遍历方法
  • keys(): 返回键名的遍历器
  • values(): 返回键值的遍历器
  • entries(): 返回键值对的遍历器
  • forEach(): 使用回调函数遍历每个成员

由于 Set 结构没有键名,只有键值,所以 keys 方法和 values 方法的行为完全一致,都是只返回键值。

let set = new Set(['red', 'green', 'blue'])

for (let item of set.keys()) {
  console.log(item) // red green blue
}

for (let item of set.values()) {
  console.log(item) // red green blue
}

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

set.forEach((value, key) => console.log(key + ':' + value))
// red:red
// green:green
// blue:blue

WeakSet

WeakSet 结构和 Set 很相似,但是他们还是有区别的

  1. WeakSet 数组里面添加的成员,只能是对象,不能是其他类型的值。
  2. WeakSet 里面的成员对象是弱引用,当其它引用不再引用就会在内存回收机制的时候回收调里面的对象,不理 WeakSet 数组里面有引用。
  3. WeakSet 不可遍历,因为不知道回收机制什么时候触发,所以数组不是连续数组。

构造 WeakSet 和 Set 一样,需要通过 new 来造建函数,并且可以接受一个数组或者类似数组的对象作为参数。 任何具有 Iterable 接口的对象,都可以作为 WeakSet 的参数, 并且添加进 WeakSet 的成员也只能唯一,没有重复的对象成员,根据对象地址指针来判断。

const ws = new WeakSet()

const a = [[1, 2], {name: 'c', age: 28}]
const ws = new WeakSet(a) // 直接传数组作为参数,会自动把数组里面的对象转为 WeakSet 的实员对象。
const ws1 = new WeakSet([2,3]) // 如果数组里面是基础类型不是对象,一样会报错 Uncaught TypeError: Invalid value used in weak set

操作WeakSet 的方法和Set一样。

  • WeakSet.prototype.add(value): 向 WeakSet 实例添加一个新成员。
  • WeakSet.prototype.delete(value): 已经 WeakSet 指定成员。
  • WeakSet.prototype.has(value): 查找某个值是否存在 WeakSet 实例中,并返回布尔值。

但是 WeakSet 没有 size 属性,没办法遍历它的成员。

const ws = new WeakSet()
const obj = {}
const foo = {}
ws.add(window)
ws.add(obj)

ws.has(window) // true
ws.has(foo) // false 判断是根据内存地址来判断的。