set
# set
ES6 新增的一种新的数据结构,类似于数组,但成员是唯一且无序的,没有重复的值。
Set 本身是一种构造函数,用来生成 Set 数据结构。
集合(Set)并不是一种数据类型,而是 ES6 提供的新的数据结构
# WeakSet
WeakSet 对象允许你将弱引用对象储存在一个集合中
# WeakSet 和 set 区别
WeakSet 只能储存对象引用,不能存放值,而 Set 对象都可以
WeakSet 对象中储存的对象值都是被弱引用的,即垃圾回收机制不考虑 WeakSet 对该对象的应用,如果没有其他的变量或属性引用这个对象值,则这个对象将会被垃圾回收掉(不考虑该对象还存在于 WeakSet 中),所以,WeakSet 对象里有多少个成员元素,取决于垃圾回收机制有没有运行,运行前后成员个数可能不一致,遍历结束之后,有的成员可能取不到了(被垃圾回收了),WeakSet 对象是无法被遍历的(ES6 规定 WeakSet 不可遍历),也没有办法拿到它包含的所有元素
# set 和 map 区别
共同点:集合、字典 可以储存不重复的值
不同点:集合 是以 [value, value]的形式储存元素,字典 是以 [key, value] 的形式储存
# 总结
# Set
成员唯一、无序且不重复
[value, value],键值与键名是一致的(或者说只有键值,没有键名)
可以遍历,方法有:add、delete、has
# WeakSet
成员都是对象
成员都是弱引用,可以被垃圾回收机制回收,可以用来保存 DOM 节点,不容易造成内存泄漏
不能遍历,方法有 add、delete、has
# Map
本质上是键值对的集合,类似集合
可以遍历,方法很多可以跟各种数据格式转换
# WeakMap
只接受对象作为键名(null 除外),不接受其他类型的值作为键名
键名是弱引用,键值可以是任意的,键名所指向的对象可以被垃圾回收,此时键名是无效的
不能遍历,方法有 get、set、has、delete
# 手写 set
class Set {
constructor() {
this.items = {};
}
add(element) {
if (this.has(element)) {
return false;
} else {
this.items[element] = element;
return true;
}
}
delete(element) {
if (this.has(element)) {
delete this.items[element];
return true;
} else {
return false;
}
}
has(element) {
return Object.prototype.hasOwnProperty.call(this.items, element);
}
size() {
return Object.keys(this.items).length;
}
/* 手动实现size()
size() {
let count = 0;
for (key in this.items) {
if (this.has(key)) {
count++;
}
}
return count;
} */
values() {
return Object.values(this.items);
}
/* 手动实现values
values() {
let valuesArray = [];
for (key in this.items) {
if (this.has(key)) {
valuesArray.push(key);
}
}
return valuesArray;
} */
clear() {
this.items = {};
}
isEmpty() {
return this.size() === 0;
}
//并集
union(otherSet) {
let unionSet = new Set();
this.values().forEach((element) => {
unionSet.add(element);
});
otherSet.values().forEach((element) => {
unionSet.add(element);
});
return unionSet;
}
//交集
intersection(otherSet) {
let intersectionSet = new Set();
let biggerValues;
let smallerValues;
if (this.values().length > otherSet.values().length) {
biggerValues = this.values();
smallerValues = otherSet.values();
} else {
biggerValues = otherSet.values();
smallerValues = this.values();
}
smallerValues.forEach((x) => {
if (biggerValues.includes(x)) {
intersectionSet.add(x);
}
});
return intersectionSet;
}
//差集
difference(otherSet) {
let differenceSet = new Set();
this.values().forEach((x) => {
if (!otherSet.has(x)) {
differenceSet.add(x);
}
});
return differenceSet;
s;
}
//子集
isSubsetOf(otherSet) {
if (this.size() > otherSet.size()) {
return false;
}
if (this.size() === 0) {
//空集是任何集合的子集
return true;
}
return this.values().every((x) => {
//every不会对空数组进行检测
if (!otherSet.has(x)) {
return false;
} else {
return true;
}
});
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116