Set和WeakSet

数据结构Set和WeakSet

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

Set

属性

  • Set.prototype.constructor:构造函数,默认就是Set函数。
  • Set.prototype.size:返回Set实例的成员总数。
let set = new Set()
console.dir(set.constructor); //ƒ Set()
        
console.log(set.size); // 0
set.add(1)
console.log(set.size); // 1
set.add(1)
console.log(set.size); // 1 因为成员的值都是唯一的,所以长度还是1

方法

  • Set.prototype.add(value):添加某个值,返回 Set 结构本身。
  • Set.prototype.delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
  • Set.prototype.has(value):返回一个布尔值,表示该值是否为Set的成员。
  • Set.prototype.clear():清除所有成员,没有返回值。
let set = new Set()
set.add(1).add(2).add(3).add(2) //因为返回Set结构本身,所以可以通过链式操作添加值
console.log(set); //Set(3) {1, 2, 3}

set.delete(1) //本身有这个值可以删除返回true
set.delete(5) //本身没有这个值不能删除返回false

set.has(1) //本身有这个值返回true
set.has(5) //本身有这个值返回false

set.clear()
console.log(set); //Set(0) {}

遍历

  • Set.prototype.keys():返回键名的遍历器
  • Set.prototype.values():返回键值的遍历器
  • Set.prototype.entries():返回键值对的遍历器
  • Set.prototype.forEach():使用回调函数遍历每个成员
let set = new Set()
set.add(1).add(2).add(3)

//1. Set本身就有遍历器,而for of可以遍历具有遍历器的数据结构
// 默认遍历器生成函数就是它的values方法(第一种和第三种是一样的)
for (let i of set) {
     
    console.log(i)
}
//1 2 3

//2.keys方法返回键名遍历器
for (let key of set.keys()) {
     
    console.log(key)
}
//1 2 3

//3.values方法返回键值遍历器,需要注意的是Set数据结构的键和值是一样的,所以keys方法和values方法的行为完全一致
for (let value of set.values()) {
     
    console.log(value)
}
//1 2 3

//4.entries方法返回键值对的遍历器
for (let item of set.entries()) {
     
    console.log(item);
}
//[1, 1] [2, 2], [3, 3]

//5.forEach方法使用回调函数遍历每个成员
set.forEach((key, value) => {
     
    console.log(key + value);
})
// 2, 4, 6

使用场景

  • 数组去重(除了数组去重我也不知道能干嘛,欢迎补充)
let arr = [1, 3, 4, 3, 2, 5, 4, 1]

//Set函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化。
//通过展开符展开
arr = [...new Set(arr)] //[1, 3, 4, 2, 5]

//Array.from方法可以将伪数组对象或可迭代对象转为数组
arr = Array.from(new Set(arr))

WeakSet

WeakSet用法上和Set大同小异,但是需要注意以下几点

  1. WeakSet只能存放对象
  2. WeakSet没有clear()方法
  3. WeakSet 没有size属性,没有办法遍历它的成员。
const ws = new WeakSet();
//以下代码存放的都不是对象,故而报错
ws.add(1)
// TypeError: Invalid value used in weak set
ws.add(Symbol())
// TypeError: invalid value used in weak set

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

由于这个特点,WeakSet 的成员是不适合引用的,因为它会随时消失。另外,由于 WeakSet 内部有多少个成员,取决于垃圾回收机制有没有运行,运行前后很可能成员个数是不一样的,而垃圾回收机制何时运行是不可预测的,因此 ES6 规定 WeakSet 不可遍历。
点击了解垃圾回收机制

你可能感兴趣的:(JavaScript)