- Set 用于存储任何类型的唯一值,无论是基本类型还是对象引用。
- 基本使用
- 获取元素数量
- 检测元素是否存在
- 删除元素
- 数组转换
- 去除重复
- 遍历数据
- 搜索实例
- 交集
- 差集
- 并集
- WeakSet 结构同样不会存储重复的值,它的成员必须只能是对象类型的值。
- 声明定义
- 基本操作
- 垃圾回收
- 案例操作
- 只能保存值没有键名
- 严格类型检测如字符串数字不等于数值型数字
- 值是唯一的
- 遍历顺序是添加的顺序,方便保存回调函数
对象属性最终都会转为字符串
let obj = { 1: "wgchen", "1": "willem" };
console.table(obj);
使用对象做为键名时,会将对象转为字符串后使用
let obj = { 1: "wgchen", "1": "willem" };
console.table(obj);
let hd = {[obj]: "wgchen"};
console.table(hd);
console.log(hd[obj.toString()]);
console.log(hd["[object Object]"]);
使用数组做初始数据
let hd = new Set(['wgchen', 'willem']);
console.log(hd.values()); // {"wgchen", "willem"}
Set 中是严格类型约束的,下面的数值 1
与字符串 1
属于两个不同的值。
let set = new Set();
set.add(1);
set.add("1");
console.log(set); // Set(2) {1, "1"}
使用 add 添加元素,不允许重复添加 wgchen 值。
let hd = new Set();
hd.add('wgchen');
hd.add('willem');
hd.add('wgchen')
console.log(hd.values());
let hd = new Set(['wgchen', 'willem']);
console.log(hd.size); // 2
检测元素是否存在
let hd = new Set();
hd.add('wgchen');
console.log(hd.has('wgchen')); // true
删除元素
使用 delete 方法删除单个元素,返回值为 boolean 类型。
let hd = new Set();
hd.add("wgchen");
hd.add("willem");
console.log(hd.delete("willem")); //true
console.log(hd.values()); // SetIterator {'wgchen'}
console.log(hd.has("willem")); //false
使用 clear 删除所有元素
let hd = new Set();
hd.add('hdcms');
hd.add('houdunren');
hd.clear();
console.log(hd.values());
可以使用点语法或 Array.form
静态方法将 Set 类型转为数组,这样就可以使用数组处理函数了。
const set = new Set(["wgchen", "willem"]);
console.log([...set]); // ["wgchen", "willem"]
console.log(Array.from(set)); // ["wgchen", "willem"]
移除Set中大于5的数值
let hd = new Set("123456789");
hd = new Set([...hd].filter(item => item "wgchen", "willem" => "willem"}
可以使用 forEach
遍历 Set
数据,默认使用 values
方法创建迭代器。
为了保持和遍历数组参数统一,函数中的 value与 key 是一样的。
let arr = [7, 6, 2, 8, 2, 6];
let set = new Set(arr);
//使用forEach遍历
set.forEach((item,key) => console.log(item,key));
也可以使用
forof
遍历 Set 数据,默认使用 values 方法创建迭代器。
//使用for/of遍历
let set = new Set([7, 6, 2, 8, 2, 6]);
for (const iterator of set) {
console.log(iterator);
}
下面通过历史搜索的示例体验 Set 类型
wgchen
body {
padding: 200px;
}
* {
padding: 0;
margin: 0;
}
input {
width: 200px;
border: solid 1px #d63031;
outline: none;
padding: 10px;
box-sizing: border-box;
}
ul {
list-style: none;
width: 200px;
padding-top: 20px;
}
ul li {
border: solid 1px #ddd;
padding: 10px;
margin-bottom: -1px;
}
ul li:nth-of-type(odd) {
background: #00b894;
}
let obj = {
words: new Set(),
set keyword(word) {
this.words.add(word);
},
show() {
let ul = document.querySelector('ul');
ul.innerHTML = '';
this.words.forEach((item) => {
ul.innerHTML += ('' + item + ' ');
})
}
}
document.querySelector('input').addEventListener('blur', function () {
obj.keyword = this.value;
obj.show();
});
交集
获取两个集合中共同存在的元素
let hd = new Set(['wgchen', 'willem']);
let cms = new Set(['ycc', 'wgchen']);
let newSet = new Set(
[...hd].filter(item => cms.has(item))
);
console.log(newSet);
在集合 a 中出现但不在集合 b 中出现元素集合
let hd = new Set(['wgchen', 'willem']);
let cms = new Set(['ycc', 'wgchen']);
let newSet = new Set(
[...hd].filter(item => !cms.has(item))
);
console.log(newSet); // Set(1) {'willem'}
将两个集合合并成一个新的集合,由于 Set 特性当然也不会产生重复元素。
let hd = new Set(['wgchen', 'willem']);
let cms = new Set(['ycc', 'wgchen']);
let newSet = [...hd, ...cms];
console.log(newSet); // ['wgchen', 'willem', 'ycc', 'wgchen']
WeakSet 结构同样不会存储重复的值,它的成员必须只能是对象类型的值。
垃圾回收不考虑WeakSet,即被WeakSet引用时引用计数器不加一,所以对象不被引用时不管WeakSet是否在使用都将删除。
因为WeakSet 是弱引用,由于其他地方操作成员可能会不存在,所以不可以进行 forEach( )
遍历等操作。
也是因为弱引用,WeakSet 结构没有 keys( ),values( ),entries( )
等方法和 size 属性。
因为是弱引用所以当外部引用删除时,希望自动删除数据时使用 WeakMap。
声明定义以下操作由于数据不是对象类型将产生错误
new WeakSet(["wgchen", "willem"]); //Invalid value used in weak set
new WeakSet("wgchen"); //Invalid value used in weak set
WeakSet的值必须为对象类型
new WeakSet([["wgchen"], ["willem"]]);
将 DOM 节点保存到 WeakSet
document.querySelectorAll("button").forEach(item => Wset.add(item));
基本操作
下面是 WeakSet 的常用指令
const hd = new WeakSet();
const arr = ["wgchen"];
//添加操作
hd.add(arr);
console.log(hd.has(arr));
//删除操作
hd.delete(arr);
//检索判断
console.log(hd.has(arr));
WeaSet 保存的对象不会增加引用计数器,如果一个对象不被引用了会自动删除。
- 下例中的数组被 arr 引用了,引用计数器+1
- 数据又添加到了 hd 的WeaSet中,引用计数还是1
- 当 arr 设置为 null 时,引用计数 -1 此时对象引用为0
- 当垃圾回收时对象被删除,这时 WakeSet 也就没有记录了
const hd = new WeakSet();
let arr = ["wgchen"];
hd.add(arr);
console.log(hd.has(arr));
arr = null;
console.log(hd); //WeakSet {Array(1)}
setTimeout(() => {
console.log(hd); //WeakSet {}
}, 1000);
wgchen
* {
padding: 0;
margin: 0;
}
body {
padding: 200px;
}
ul {
list-style: none;
display: flex;
width: 200px;
flex-direction: column;
}
li {
height: 30px;
border: solid 2px #e67e22;
margin-bottom: 10px;
display: flex;
justify-content: space-between;
align-items: center;
padding-left: 10px;
color: #333;
transition: 1s;
}
a {
border-radius: 3px;
width: 20px;
height: 20px;
text-decoration: none;
text-align: center;
background: #16a085;
color: white;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
margin-right: 5px;
}
.remove {
border: solid 2px #eee;
opacity: 0.8;
color: #eee;
}
.remove a {
background: #eee;
}
blog.csdn.net x
wgchen.blog x
csdn x
class Todos {
constructor() {}
run() {
this.items = document.querySelectorAll("ul > li");
this.lists = new WeakSet();
this.record();
this.addEvent();
}
addEvent() {
this.items.forEach(item => {
item.querySelector("a").addEventListener("click", event => {
//检测WakeSet中是否存在Li元素
const parentElement = event.target.parentElement;
if (!this.lists.has(parentElement)) {
alert("已经删除此TODO");
} else {
//删除后从记录的WakeSet中移除
parentElement.classList.add("remove");
this.lists.delete(parentElement);
}
});
});
}
record() {
this.items.forEach(item => this.lists.add(item));
}
}
new Todos().run();