来学学es6的Set的用法

288 阅读3分钟

这是我参与11月更文挑战的第15天,活动详情查看:2021最后一次更文挑战

问题

面试官: 你能讲讲es6的set吗?

面试者: 巴拉,它主要用来去重数组,字符串这些比较方便。

面试官:那你能讲讲weakSet吗?有什么不同?

面试者:。。。

以上问题纯属虚构,可能会有雷同。

今天来讲讲SetweakSet的用法。

Set

它内部的值都是唯一的,不会是重复的。如果传入是重复的数据,得到的是去重后的数据。

所以一般是用它来去重数组,字符串等等。

语法:

new Set(val)

Set是一个构造函数,val不限定类型,只要是具有Iterator接口的数据都可以。

以下数据具有Iterator接口

  • 数组
  • Map
  • Set
  • 字符串
  • 类数组,比如NodeListarguments
var set = new Set('112233')
console.log(set) // Set(3) {'1', '2', '3'}

var set = new Set([1,2,3,1,2,3])
console.log(set) // Set(3) {1, 2, 3}

可以看到打印出来的都是去重后的数据。

var set = new Set(['1',1, 1])
console.log(set) // Set(3) {'1',1}

var set = new Set([{},{}])
console.log(set) // Set(3) {{},{}}

var set = new Set([NaN,NaN])
console.log(set) // Set(3) {NaN}

Set不会发生类型转换,数字1和字符串1是不一样的。然后键值对一样对象也是不一样的,但是认为NaN是一样的,这个需要注意

实例的属性

Set.prototype.size

这个是返回set实例内部成员的个数。 它没有length属性

var set = new Set('112233')
console.log(set.size) // 3

实例的方法

Set.prototype.add(value)

往set实例中添加数据

var set = new Set([1,2,3])
set.add(4)
set.add(5)
console.log(set) // Set(5) {1, 2, 3, 4, 5}

Set.prototype.delete(value)

往set实例中删除某个数据。如果实例中不存在该数据,则删除不成功,对实例不影响。

var set = new Set([1,2,3])
set.delete(3)
console.log(set) // Set(5) {1, 2}

Set.prototype.has(value)

确实set实例中是否有value。返回布尔值。

var set = new Set([1,2,3])
console.log(set.has(3)) // true
console.log(set.has(4)) // false

Set.prototype.clear()

清空set实例的所有数据

var set = new Set([1,2,3])
set.clear()
console.log(set) // Set(0) {size: 0}

keys(),values(), entries()

这些都是Set实例的遍历方法,返回的是Iterator的对象,set的key和value都是同一个,所以keys(),values()得到的都是同一个。

而且 Set实例本身也是有Iterator接口,它也可以进行for-of遍历。

var set = new Set([1,2,3])
for(let key of set) {console.log(key)} // 1 2 3
for(let key of set.keys()) {console.log(key)} // 1 2 3
for(let key of set.values()) {console.log(key)} // 1 2 3
for(let key of set.entries()) {console.log(key)} // [1,1] [2,2] [3,3]

除了上面的,还有个forEach方法,可以对Set实例遍历

var set = new Set([1,2,3])
set.forEach((value,key) => {consoe.log(value, key)}) // value和key一样 1 1  2 2 3 3

扩展运算符

因为set实例是有Iterator的接口,它可以使用扩展运算符转成数组。

var set = new Set([1,2,3])
console.log([...set]) // [1, 2, 3]

WeakSet

WeakSet和Set类似,也是限制值是不能重复的,值也得是具有Iterator的接口的数据才可以。但是值必须是对象,不能是其它类型。 比如数组,数组的每项都需要是对象类型。

new WeakSet([1,2,3]) // error: Invalid value used in weak set
new WeakSet([[1],[2],[3]]) // success
new WeakSet([{a:1},{a:2}]) // success

还有一个和Set不同的是,它是弱引用,空闲的时候垃圾回收机制会自动回收,无需手动去清空处理。

它的实例没有size属性,只有add,delete,has方法。

var weakset = new WeakSet()
var arr = [[1]]
weakset.add(arr) // WeakSet {Array(1)}
weakset.size // undefined
weakset.has(arr) // true
weakset.delete(arr) // WeakSet {}

参考

Set 和 Map 数据结构