Set 、WeakSet 、 Map 、WeakMap
Set
用于存储任何类型的唯一值,无论是基本类型还是对象引用
- 只能保存值没有键名
- 值是唯一的,重复的键名将合并为一个
- Set值唯一判断采用严格类型检测(===)
- 遍历顺序是添加的顺序,方便保存回调函数
- 对象作为键名最终都会转为字符串
- 使用
add
添加元素,使用delete
删除元素 - 可以使用
Array.form
静态方法转换为数组
Set的初始化
Set 利用 new
关键字创建
示例:
//使用new关键字创建Set,利用add 方法添加元素
let set1 = Set();
set1.add(1);
set1.add(2);
//使用数组初始化Set
let set2 = new Set([1,"1",2,3,4]);
Set 元素唯一
Set 采用严格类型约束(===为true),下面的数值1与字符串1属于两个不同的值。另外两个对象总是不相等的
示例:
let set = new Set([1,"1",2,3,4]);
console.table(set);
输出:
对于引用类型,如果两个变量引用同一块内存,那么这两个变量是严格相等的。例如:
let obj1 = {name : "john",age : 28}
let obj2 = obj1;
console.log(obj1 === obj2);
console.table(new Set([obj1,obj2]));
输出:
基本操作
获取元素数量
Set利用set.size
获取元素数量
示例:
let set = new Set([1,"1",2,3,4]);
console.table(set.size);//输出 : 5
元素是否存在
Set利用set.has()
获取元素数量
let set = new Set([1,"1",2,3,4]);
console.table(set.has(1));//输出:true
遍历
set也有forEach()
方法,使用keys()/values()/entries()
都可以返回迭代对象,因为set类型只有值所以keys与values方法结果一致。
let set = new Set([1,2,3]);
set.forEach((value, key) => console.log(key + ' : ' + value));
添加、删除
let set = new Set(['创新实验室','学习js']);
//添加元素
set.add(1);
set.add(2);
console.table(set);
//删除元素
set.delete(1);
console.table(set);
//清除所有元素
set.clear();
console.table(set);
输出:
过滤
可以使用点语法
或Array.form
静态方法将Set类型转为副本,这样就可以使用拆分处理函数了
过滤掉Set中大于5的数值:示例:
let set = new Set([1,3,2,4,6,5,7,8,9]);
set = new Set([...set].filter(item => item < 5));
console.table(set);
输出:
交集、并集、差集
let a = new Set([1,2,3]);
let b = new Set([4,3,2]);
//并集
let union = new Set([...a, ...b]);
console.table(union);
//交集
let intersect = new Set([...a].filter(x => b.has(x)));
console.table(intersect);
//差集
let difference = new Set([...a].filter(x => !b.has(x)));
console.table(difference);
输出:
利用set特性 实现去重
let str = "这是一串重复重复的字符字符字符";
let arr = [1,2,1,4,3,3,2,4];
console.log([...new Set(str)].toString());
console.table([...new Set(arr)]);
输出:
WeakSet
WeakSet结构同样不会存储重复的值,它的成员必须只能是对象类型的值,否则将报错
- 垃圾回收不考虑WeakSet,即被WeakSet引用时引用计数器不加一,所以对象不被引用时不管WeakSet是否在使用都将删除
- 因为WeakSet 是弱引用,由于其他地方操作成员可能会不存在,所以不可以进行
forEach( )
遍历等操作 - 因为弱引用,WeakSet 结构没有
keys( ),values( ),entries( )
等方法和size
属性 - 因为是弱引用所以当外部引用删除时,希望自动删除数据时使用 WeakMap
- WeakSet的大部分操作与Set差不多
基本操作
WeakSet的大部分操作与Set差不多
const ws = new WeakSet();
const arr = ["this is a str"];
//添加操作
ws.add(arr);
console.log(ws.has(arr));
//删除操作
ws.delete(arr);
//检索判断
console.log(ws.has(arr));
垃圾回收
WeaSet保存的对象不会增加引用计数器,如果一个对象不被引用了会自动删除。
Map
Map是一组键值对的结构,函数、对象、基本类型都可以作为键或值
初始化
- 可以接受一个数组作为参数,该数组的成员是一个表示键值对的数组。
let map = new Map([
["name","john"],
["age","20"]
]);
console.table(map);
输出:
- 使用
set
方法添加元素,可以连续添加
let map = new Map();
map.set("name","mike").set("age",20);
console.table(map);
基本操作
- 获取数量
map.size
: 属性,返回元素数量 - 元素检测
map.has(key)
: 传入键值,返回该元素是否存在的布尔值 - 增删查
方法名 参数 说明 map.get(key)
key : 键值 根据键值读取元素 map.set(key,value)
key : 键值,value : 值 添加一个map元素 map.set.delete(key)
key : 键值 删除一个map元素 map.set.clear()
无 清除所有元素
遍历
- 使用
map.keys()/map.values()
遍历
let map = new Map([
[1 , "一"],
[2 , "二"],
[3 , "三"],
[4 , "四"],
[5 , "五"]
]);
//遍历键值
for (const key of map.keys()) {
console.log(key);
}
//遍历值
for (const value of map.values()) {
console.log(value);
}
- 使用
map.forEach()
let map = new Map([
[1 , "一"],
[2 , "二"],
[3 , "三"],
[4 , "四"],
[5 , "五"]
]);
//1. key.value
map.forEach((key,value) =>
console.log(`${key} : ${value}`)
);
//2. entries返回迭代器
map.forEach((entries,value) =>
console.log(`${entries} : ${value}`)
);
数组转换
可以使用展开语法
或 Array.form
静态方法将Map类型转为数组,这样就可以使用数组处理函数了
具体流程类似set
WeakMap
WeakMap 对象是一组键/值对的集
- 键名必须是对象
- WeaMap对键名是弱引用的,键值是正常引用
- 垃圾回收不考虑WeaMap的键名,不会改变引用计数器,键在其他地方不被引用时即删除
- 因为WeakMap 是弱引用,由于其他地方操作成员可能会不存在,所以不可以进行forEach( )遍历等操作
- 因为弱引用,WeakMap 结构没有
keys( ),values( ),entries( )
等方法和 size 属性 - 当键的外部引用删除时,希望自动删除数据时使用WeakMap
基本操作
let weakMap = new WeakMap();
let obj = {
name:"a"
};
//添加操作
weakMap.set(obj,"A");
//删除操作
weakMap.delete(obj);
//检索判断
weakMap.has(obj);
垃圾回收
WakeMap的键名对象不会增加引用计数器,如果一个对象不被引用了会自动删除。
- 当通过
weakMap.set()
添加的对象被删除时内存即清除,因为WeakMap是弱引用不会产生引用计数 - 当垃圾回收时因为对象被删除,这时WakeMap也就没有记录了