Set
介绍
- Set结构是es6中新的数据结构,类似数组,但是值都是唯一的,不重复,可以理解为set构造函数天生就会把我们传进去的数组进行去重。
- 拥有Iterator接口,支持for of
let set = new Set([1,3,5,5,6,6])
set // [1,3,5,6]
set.size // 4
Set实例的属性和方法
- 属性:拥有size属性,set.prototype.size 返回Set实例的成员总数。
- 方法:包括两类,操作方法和遍历方法。
操作方法
- add(val) : 添加值,返回结构本身
- delete(val) :删除某个值,返回一个布尔值,表示是否删除成功
- has(val) : 返回一个布尔值,表示是否存在某个值
- clear() : 清空数据,无返回值
set.add(1).add(3).add(3)
set.size // 2
set.has(1) // true
set.has(2) // false
set.delete(3)
set.has(3) // false
遍历方法
拥有四个遍历方法,都差不多
- keys() :返回一个包含键名的遍历器
- values() : 返回键值的遍历器
- entries() : 返回键值对的遍历器
- forEach() : 和普通的forEach一样
let set = new Set(['a','b','c'])
for(let i of set.keys()){
console.log(i)
}
// a
// b
// c
let set = new Set(['a','b','c'])
for(let i of set.entries()){
console.log(i)
}
// ['a','a']
// ['b','b']
// ['c','c']
这里values和keys的效果一样,因为set结构不存在键值对,键就是值,值就是键,键和值是同一个值,并且根本不需要他来遍历set结构,直接for of 就可以,因为他的遍历器生成函数就是values方法
Set.prototype[Symbol.iterator] ==== Set.prototype.values
使用扩展运算符操作set
-
扩展运算符(...)内部使用for...of循环,所以也可以用于 Set 结构。 阮一峰老师原话。
-
数组的扩展中讲了,任何定义了遍历器(Iterator)接口的对象,都可以用扩展运算符转为真正的数组。操作一下:
let set = new Set(['a','b','c','c'])
let arr = [...set] // [ 'a', 'b', 'c' ]
console.log(Array.isArray(arr)); // true
通过扩展运算符,实现数组去重
- 这三种也比较有用,实现交集、并集、和差集。
let a = new Set([1, 2, 5, 6])
let b = new Set([1, 2, 4, 6])
let union = new Set([...a, ...b])
console.log("TCL: union", union) // TCL: union Set { 1, 2, 5, 6, 4 }
let intersect = new Set([...a].filter((e) => b.has(e)))
console.log("TCL: intersect", intersect) // TCL: intersect Set { 1, 2, 6 }
let diff = new Set([...a].filter((e) => !b.has(e)))
console.log("TCL: diff", diff) // TCL: diff Set { 5 }
- 另外,遍历过程无法改变set的值,可以通过处理一个新的set再重新赋值的形式做到,比如利用map和Array.from()这两种返回新数组的方法实现。
let set = new Set([1,3,5])
set = new Set([...set].map( e => e*2))
// Set(3) {2, 6, 10}
set = new Set(Array.from(set, e => e*2))
// 结果一样
WeakSet
与Set区别
- WeakSet只能存对象
- WeakSet就像它的名字一样,WeakSet中的值都是弱引用的,什么是弱引用,弱引用又有什么用呢?
- 弱引用就是垃圾回收不考虑WeakSet对对象的引用。因此我们可以利用弱引用的特性,存储一些动态的依赖数据,这样就可以不用主动去管理它,不引用的数据会自动被回收掉。
- WeakSet不能被遍历,没有size属性,可以进行添加、删除、has判断
const b = [{ a: 1 }, { b: '2' }];
const ws = new WeakSet(b);
const obj = { c: 3 };
ws.add(obj);
console.log(ws);
console.log(ws.has(obj));