欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ES6/7学习之Set WeakSet

程序员文章站 2023-12-21 21:34:34
...

带键(key)的集合

Map、WeakMap(映射) 和 Set(集合) 对象承载的数据元素可以按照插入时的顺序被迭代遍历。

Set

Set对象是一组不可重复的、唯一的值的集合,可根据插入顺序遍历。

与Array的比较
数组中用于判断元素是否存在的indexOf 函数效率低下。
Set对象允许根据值删除元素,而数组中必须使用基于下标的 splice 方法。
数组的indexOf方法无法找到NaN值。
Set对象存储不重复的值,所以不需要手动处理包含重复值的情况。

使用

let set = new Set(); // 创建空的Set
set.add(1); // 添加
console.log(set.has(1)); // 判断是否包含,返回Boolean
set.delete(1); // 删除

let set2 = new Set([1, 2]); // 创建并初始化Set,初始化参数是一个可被迭代的(iterable)对象
console.log(set2.size); // 获取数量
set2.clear(); // 清空

遍历

let set = new Set([1, 2, 3]);
let entries = set.entries(); // 返回按插入顺序包含key(key=value)/value映射的Iterator迭代器对象
let keys = set.keys(); // 返回按插入顺序包含key(key=value)的Iterator迭代器对象
let values = set.values(); // 返回按插入顺序包含value的Iterator迭代器对象

// for of遍历
for (let item of set) {}
for (let [key,value] of entries) {}
for (let key of keys) {}
for (let value of values) {}

// forEach遍历(Iterator不能用forEach遍历)
set.forEach((value,key) => {});

与Array String交互

let arr = [1,1,2,3];
let set = new Set(arr); // Array转Set,重复的值被忽略
console.log(set); // Set(3) {1, 2, 3}

let str = '1123';
let set2 = new Set(str); // 转化时会将string转化为数组
console.log(set2); // Set(3) {1, 2, 3}

let arr2 = Array.from(set); // Set转Array
let arr3 = [...set]; // 效果同arr2,展开运算符本质上是将Set对象转换成数组

应用

// 数组去重
console.log(Array.from(new Set([1,1,2,3,3,4,5,6,6,7,8,2,4]))); // [1,2,3,4,5,6,7,8]

let set1 = new Set([1,2,3,4,5]);
let set2 = new Set([3,4,5,6,7,8]);
// 求交集
console.log(new Set([...set1].filter(v=>set2.has(v)))); // Set(3) {3, 4, 5}

// 求差集
let arr1 = [...set1].filter(v=>!set2.has(v));
let arr2 = [...set2].filter(v=>!set1.has(v));
console.log(new Set([...arr1, ...arr2])); // Set(5) {1, 2, 6, 7, 8}

WeakSet

与Set的区别
1.WeakSet必须是一组对象的集合,值必须是对象类型(Object),不能是基础数据类型
2.值所引用(指向)的对象是弱引用。(弱引用解释参考 ES6/7学习之Map WeakMap
3.Set是可迭代的(iterable),WeakSet是不可迭代的(key是弱引用)。

// 个人理解举例
let obj = {
    name:'乔峰'
};
let obj2 = {
    name:'虚竹'
};
let map = new Map();
map.set(obj, 1);
let weakMap = new WeakMap();
weakMap.set(obj2, 1);

obj = null; // 手动删除全局对{name:'乔峰'}的引用
obj2 = null; // 手动删除全局对{name:'虚竹'}的引用

setTimeout(()=>{
    console.log(map); // Map(1) {{…} => 1}
    console.log(weakMap); // WeakMap {}
}, 10000); // 设置时间长点,等待垃圾回收

使用

// 弱引用不能被枚举。所以WeakSet不能被遍历
let obj = {};
let weakSet = new WeakSet(); // 创建
weakSet.add(obj); // 添加
console.log(weakSet.has(obj)); // 判断是否包含
weakSet.delete(obj); // 删除

// WeakSet的key是弱引用,所以WeakSet是不可被迭代的
// 下面代码报错:weakSet is not iterable
for(let item of weakSet) {}

// weakSet.clear()已被废弃,可重新创建一个空WeakSet替换来实现清空
weakSet = new WeakSet();

应用场景
暂时不知道很合适的场景

参考

MDN:
Keyed collections
Set MDN
WeakSet MDN

相关标签: ES6/7

上一篇:

下一篇: