ES6:Set() 与 WeakSet()
Set() 是ES6新增的一种类似Array的集合类型,它最标志的特性就是所有元素都是唯一的不重复的
新建一个Set()
const people = new Set(['Tom', 'Jerry', 'Mario']);
在控制台上打印可以看到它的属性和可以使用的一些方法:
size
Set计算长度的单位是size而不是length
add() 与 delete() 方法
从名字上可以明确看出,一个是添加一个是删除:
需要注意的是Set没有索引属性,delete() 需要使用的是元素本身,他会返回true或者false表示删除是否成功
因为它的元素是唯一不重复的,所以添加一个重复的元素是没有效果的:
但是它与对象不同,对象对于字符串5和数字5都会强制转换字符串存储,Set则可以存储两种数据类型:
has() 方法
has() 方法用于检测是否含有该元素:
clear() 方法
clear() 方法用于清除Set的所有元素:
可使用Iterator迭代器
可以通过 values() 方法,他会返回一个SetIterator ,就可以使用 next() 方法了:
可使用for of 与forEach() 遍历
const people = new Set(['Tom', 'Jerry', 'Mario']);
for(let item of people) {
console.log(item);
}
console.log('=========================');
people.forEach(element => {
console.log(element);
});
Set使用 forEach() 方法与数组一样都是三个参数,而因为Set不具备索引值,为了统一用法,其第二个参数就是与第一个一样都为当前元素了:
const people = new Set(['Tom', 'Jerry', 'Mario']);
people.forEach((value, index, arr) => {
console.log(value, index, arr);
});
console.log('===============================================');
const peopleArr = ['Tom', 'Jerry', 'Mario'];
peopleArr.forEach((value, index, arr) => {
console.log(value, index, arr);
});
数组去重应用
有这样一个数组,里面有很多重复的元素,使用Set的特性可以快速去重:
const arr = [1, 3, 5, 6, 3, 2, 4, 5, 5, 6, 6, 4];
const arrSet = new Set(arr);
const uniqueArr = [...arrSet];
console.log(uniqueArr);
先使用Set方法新建一个Set集合,因为可迭代,就可以使用拓展运算符来新建一个去重后的新数组
WeakSet()
WeakSet() 与 Set() 使用相似,但它们又有一些不同,先新建一个WeakSet():
let p1 = { name: 'Tom', age: '18' };
let p2 = { name: 'Jerry', age: '21' };
const people = new WeakSet([p1, p2]);
1️⃣ 一眼就可以看出它与Set的第一个不同:它的成员只能为对象
在控制台打印它:
2️⃣ 可以看出它也不能使用 add() 与 clear()
3️⃣ 它也不能使用for of 与 forEach() ,因为他没有size属性
弱引用,不被计入垃圾回收
这是 WeakSet() 的最大特点,从下面这串代码可以理解:
同样定义两个people:
let p1 = { name: 'Tom', age: '18' };
let p2 = { name: 'Jerry', age: '21' };
先定义一个数组形式的集合,并通过赋值null删除p2:
const peopleArr = [p1, p2];
console.log(peopleArr);
p2 = null;
console.log(peopleArr);
发现是无法在数组中实现去除p2,这就是 内存泄漏
当删除p2时数组还保留对其的引用,就导致数组中的p2还是原来的值
而使用 WeakSet() 就不会出现这个问题:
const peopleWSet = new WeakSet([p1, p2]);
console.log(peopleWSet);
p2 = null;
console.log(peopleWSet);
发现其实跟数组是一样的,但过一段时间我们在控制台在打印一遍peopleWSet:
这是因为它是自动清理,而不是一直监听,实时清理