1、Set
- Set 类似于数组,但是它的成员的值都是唯一的
- Set 本身是一个构造函数
- Set 函数参数可以是一个数组(或者具有iterable接口的其他数据结构)
- Set 遍历顺序就是插入顺序
var set = new Set([0, 1, 2, 2, 1]);
//Set { 0, 1, 2}
实例的属性
- size
- constructor
var set = new Set([0, 1, 2]);
set.size //3
set.constructor默认指向Set函数
实例的操作方法
- add(value): Set
- delete(value): boolean
- has(value): boolean
- clear(): void
add() 返回Set结构本身,可以链式调用
var set = new Set([0, 1, 2]);
set.add(3).add(4);
set.delete(0); //true
set.delete(5); //false
set.has(1); //true
set.clear();
set.size; //0
实例的遍历方法
- keys()
- values()
- entries()
- forEach()
Set结构的键名和键值是同一个值,keys()和values()执行结果一样。Set构造的实例默认可遍历,可以直接变量实例。
var set = new Set(['a', 'b', 'c']);
for(let item of set.keys()){
console.log(item)
}
//'a'
//'b'
//'c'
for(let item of set.entries()){
console.log(item)
}
//['a', 'a']
//['b', 'b']
//['c', 'c']
for(let item of set){
console.log(item)
}
//'a'
//'b'
//'c'
注意:Set的遍历顺序就是插入顺序
应用
数组去重
扩展运算符(...)和Set结构结合实现数组去重
var set = new Set([-0, NaN, 0 1, 2, NaN,2, 1]);
[...set]; //[0, NaN, 1, 2]
Array.from()与Set结构结合实现数组去重
var set = new Set([-0, NaN, 0 1, 2, NaN,2, 1]);
Array.from(set); //[0, NaN, 1, 2]
上述去重,相等于使用===运算符(不过认为NaN是相等的),对于引用类型数据,如果内存地址不同,是没法去重的
var set = new Set([{a:'a'}, {a:'a'}]);
Array.from(set); //[{a:'a'}, {a:'a'}]
实现并集、交集、差集
var a = new Set([1, 2, 3]);
var b = new Set([4, 3, 2]);
var union = new Set([...a, ...b]);
//Set {1, 2, 3, 4}
var intersect = new Set([...a].filter(x => b.has(x));
//Set {2, 3}
var difference = new Set([...a].filter(x => !b.has(x))
//Set {1}
2、WeakSet
WeakSet 区别于 Set
- WeakSet 成员只能是对象,而不是其他类型值
- WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑该对象的引用
- WeakSet 不可遍历
var a = [[1, 2], [3, 4]];
new WeakSet(a);
//WeakSet {[1,2], [3,4]}
new WeakSet([3, 4]);//报错
注意:成为WeakSet的成员是a数组的成员,而不是a数组本身
实例的方法
- add(value): WeakSet
- delete(value): boolean
- has(value): boolean
没有size属性,没有遍历相关的方法
var a = [[1, 2], [3, 4]];
var b = new WeakSet();
b.add(a).add(a);
b.delete(a);
b.has(a);
应用
存储DOM节点,而不用担心节点从文档移除时会引起内存泄漏