1》概念
Set数据结构类似于数组但是成员的值是唯一的,没有重复值;
Set本身是一个构造函数用于生产Set数据结构,Set函数可以接受一个数组(或类数组),对象作为参数用于初始化
判断是否相等:向set加入值的时候,不会发生类型转换(所以5和“5”是不同的),Set内部判断两个值是否是不同的,它类似于全等操作符,但是有不同主要是Set内部判读NaN等于自身,而全等操作符认为NaN不等于自身,对象总是不相等的
const s = new Set();
[2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x));
for (let i of s) {
console.log(i);}
// 2 3 5 4
const arr=[1,2,3,4,4,];
console.log([...new Set(arr)]);//[1, 2, 3, 4]
const item=new Set(document.querySelectorAll("div"));
console.log(item.size);//4
let arr=[NaN,1,2,3,3,"3",NaN]
let set=new Set(arr);
console.log([...set]);//[NaN, 1, 2, 3, "3"]
let a={"a":1};
let b={"a":1};
//let c=b;加上这段代码set.size仍然为2
let set=new Set();
set.add(a);
set.add(b);
set.add(c);
console.log(set.size);//2
2>Set实例的方法分为两大类(操作方法和遍历方法):
(1)操作方法(4个)
1)add(value):添加某个值,返回 Set 结构本身。
let set=new Set();
console.log(set.add(1).add(2).add(2));//Set(2) {1, 2}
2)delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
let set=new Set();
console.log(set.add(1).add(2).add(2));
console.log(set.delete(1));//true
3)has(value):返回一个布尔值,表示该值是否为Set的成员。
let set=new Set();
console.log(set.add(1).add(2).add(2));
console.log(set.has(2));//true
4)clear():清除所有成员,没有返回值。
let set=new Set();
console.log(set.add(1).add(2).add(2));
console.log(set.clear());
console.log(set);//set(0) {}
(2)遍历方法(4个):
keys(),values(),enterise()返回都是遍历器对象,由于 Set 结构没有键名,只有键值,所以keys方法和values方法的行为完全一致。
1)keys():返回键名的遍历器
let set = new Set(['red', 'green', 'blue']);
console.log(set.keys());//SetIterator {"red", "green", "blue", "orange"}
for (let item of set.keys()) {
console.log(item);
}// red// green// blue
2)values():返回键值的遍历器
for (let item of set.values()) {
console.log(item);
}// red// green// blue
可以省略values方法,直接用for...of循环遍历Set。
for(let item of set){
console.log(item);
}// red// green// blue
3)entries():返回键值对的遍历器
for (let item of set.entries()) {
console.log(item);
}// ["red", "red"]// ["green", "green"]// ["blue", "blue"]
4)forEach():使用回调函数遍历每个成员
set.forEach((value,key)=>console.log(key+":"+value))
扩展运算符...内部使用for...of循环,所有也可以用于Set结构
let set=new Set([1,2,3,4,5,5,3]);
console.log([...set]);//[1,2,3,4,5]
3》Set转换
1)Set数据结构转换成数组:Array.from
let set=new Set([1,2,3,4,5,5,3]);
console.log(Array.from(set));
4》应用:
1)数组的map和filter方法也可以间接用于set,因此 Set 可以很容易地实现并集、交集和差集。
let set=new Set([1,2,3]);
set=new Set([...set].map(x=>x*2));
console.log(set)
let a=new Set([1,2,3]);
let b=new Set([4,3,2]);
//并集
var union=[...new Set([...a,...b])]
console.log(union);//[1, 2, 3, 4]
//交集
var intersect=[...a].filter(x=>b.has(x));
console.log(intersect);//[2, 3]
//差集
var difference=[...a].filter(x=>!b.has(x));
console.log(difference);//[1]
2)同步改变原来的 Set 结构,目前没有直接的方法,但有两种变通方法。
一种是利用原 Set 结构映射出一个新的结构,然后赋值给原来的 Set 结构;
// 方法一
let set = new Set([1, 2, 3]);
set = new Set([...set].map(val => val * 2));// set的值是2, 4, 6
另一种是利用Array.from方法。
// 方法二
let set = new Set([1, 2, 3]);
set = new Set(Array.from(set, val => val * 2));// set的值是2, 4, 6
4》WeakSet
1.概念
WeakSet结构与Set类似,也是不重复的值的集合,但是它与Set有两个区别:
1)WeakSet的成员只能是对象,不能是其他类型的值
let ws=new WeakSet();
ws.add(1);//报错
2)WeakSet中的对象都是弱引用,即垃圾回收机制不考虑WeakSet对该对象的引用,如果其他对象不再引用该对象,那么垃圾回收机制会自动回收该对象所占的内存
它适合临时存放一组对象那个,以及存放跟对象绑定的信息,它的一个用处就是存储DOM节点(不用担心这些节点从文档移除时,会引发内存泄露)
WeakSet的成员是不适合引用的因为它会随时消失,另外WeakSet内部有多少个成员取决于垃圾回收机制有没有运行,运行前后可能成员数不一样,而垃圾回收机制何时运行是不可预测的因此WeakSet不遍历。