这是我参与11月更文挑战的第15天,活动详情查看:2021最后一次更文挑战
问题
面试官: 你能讲讲es6的set吗?
面试者: 巴拉,它主要用来去重数组,字符串这些比较方便。
面试官:那你能讲讲weakSet吗?有什么不同?
面试者:。。。
以上问题纯属虚构,可能会有雷同。
今天来讲讲Set和weakSet的用法。
Set
它内部的值都是唯一的,不会是重复的。如果传入是重复的数据,得到的是去重后的数据。
所以一般是用它来去重数组,字符串等等。
语法:
new Set(val)
Set是一个构造函数,val不限定类型,只要是具有Iterator接口的数据都可以。
以下数据具有Iterator接口
- 数组
- Map
- Set
- 字符串
- 类数组,比如
NodeList,arguments
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 {}