一、Set
1、概述:
-
ES6提供新的数据结构Set,类似于数组,但是成员的值是唯一的,没有重复值。也就是说Set是不重复的值的集合
-
没有键名,只有键值,或说键名和键值是同一个值,两个值永远是相等的
-
接受一个数组作为参数,用来初始化
const set = new Set([1,2,3,4,4]);
consle.log(set);//[1,2,3,4]
console.log([...set]);//[1,2,3,4]
复制代码
2、属性和方法
操作方法:
-
.add( ) 添加某一个值,返回的是Set结构本身
-
.delete( ) 删除某个值,返回一个布尔值,表示删除是否成功
-
.has( ) 返回一个布尔值,表示该值是否为Set的成员
-
.clear( ) 清除所有成员,没有返回值
遍历方法:
- .keys( ) 返回键名
- .values( ) 返回键值
因为Set没有键名只有键值,或说键名和键值是同一个值,所以.values( )和.keys()行为一致
Set结构的实例默认可遍历,所以可以省略.values方法;
let set = new Set(["red", "green", "blue"]);
for (let i of set.keys()) {
console.log("set.keys:", i);
}
let set2 = new Set(["red", "green", "blue"]);
for (let i of set2.values()) {
console.log("set.values:", i);
}
let set4 = new Set(["red", "green", "blue"]);
for (let i of set4) {
console.log("Set结构的实例默认可遍历:", i);
}
复制代码
- .entries( ) 返回键值对
- .forEach( )
3、Set结构如何转为数组:使用Array.from
Array.from****方法可以将 Set 结构转为数组
4、使用场景:
(1)去除数组重复成员
//实例1
const set = new Set([1, 2, 3, 4, 4]);
console.log(set);//[1,2,3,4]
//实例2
const items = new Set([1, 2, 3, 4, 4, 5, 6, 6]);
const array = Array.from(items);//[1,2,3,4,5,6]
//实例3
function dedupe(array){
return Array.from(new Set(array));//Array.from方法可以将Set结构转为数组
}
dedupe([1,1,2,3]);//[1,2,3]
复制代码
(2)去除字符串重复字符
const str = "ascddsdfg";
const DEPLICATE_STR = new Set(str);
console.log([...DEPLICATE_STR].join(''));//ascdfg
复制代码
join( )将数组中的所有元素转换成一个字符串;
(3)求并集/交集/差集
数组的map和filter方法可以间接用于Set,Set本身没有map和filter方法的哦~
let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);
let union = [...new Set([...a, ...b])];
console.log("并集=", union); //[1,2,3,4]
let intersect = [...new Set([...a].filter((x) => b.has(x)))];
console.log("交集=", intersect); //[2,3]
let difference = Array.from(new Set([...a].filter((x) => !b.has(x))));
console.log("差集=", difference); //[1]
复制代码
5、WeakSet和Set的区别:
WeakSet和Set的区别:
-
都是不可重复值的集合
-
成员只能是对象
-
没有size属性,不可遍历
用处:
WeakSet的一个用处,是储存DOM节点,而不担心这些节点从文档移除时,会引发内存泄漏;
二、Map
1、概述
-
本质上是健值对的集合,类似集合;
-
传统键值对都是“字符串-值”的对应,有所限制,所以Map结构提供了“值-值”的对应;
-
可以遍历,可以跟各种数据格式转换
-
接受一个数组作为参数,数组成员是一个个表示键值对的数组;
-
Set和Map都可以生成新的Map;
-
只有对同一个对象的引用,Map 结构才将其视为同一个键;
Map 的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键。
const map = new Map();
map.set(['aaa',5]);
console.log(map.get(['aaa']));//undefined
//只有对同一个对象的引用,Map 结构才将其视为同一个键;所以必须要指向同一个对象,将其存为一个对象;
const map = new Map();
const k1 = ['aaa'];
map.set(k1,5);
console.log(map.get(k1));//5
复制代码
2、属性和方法
操作方法:
-
.set( )
-
.get( )
-
.delete( )
-
.has( )
-
.clear( )
遍历方法:
-
.keys( ) 返回键名的遍历器
-
.values( ) 返回键值的遍历器
-
.entries( ) 返回所有成员的遍历器
-
forEach( ) 遍历Map的所有成员
Map的遍历顺序就是插入的顺序
3、与其他数据结构的互相转换
(1)Map转数组: 使用扩展运算符
(2)数组转Map
(3)Map转对象:Object.create( )
(4)对象转Map:Object.entries( )
(5)Map转JSON
(6)JSON转Map
//1、Map转数组
const map0 = new Map().set(1,'a').set(2,'b');
console.log(":",[...map0]);//[{1,'a'},{2,b}]
console.log("Map转数组:",[...map0].keys());//[1,2]
console.log("Map转数组:",[...map0].values());//['a','b']
//2、数组转Map,将数组直接传入Map构造函数
new Map([
[true,7],
[{foo:3},['abc]]
])
//3、Map转对象
const map1 = new Map().set(1,'a').set(2,'b');
function strMapToObj(strMap){
let obj = Object.create(null);//创建一个空对象,这样创建的对象干净,除了自身属性之外没有其他属性和方法
for(let [k,v] of strMap){
obj[k] = v;
}
return obj
}
strMapToObj(map1);
//4、对象转数组
const obj1 = {1:'a',2:'b'}
let map2 = new Map(Object.entries(obj))//Object.entries()返回一个给定对象自身可枚举属性的键值对数组[['1','a'],['2','b']]
复制代码
4、使用场景:
可以使用数组的map和filter方法,Map本身是没有map和filter方法的
(1)实现Map的过滤和遍历
const map0 = new Map().set(1,'a).set(2,'b).set(3,'c');
const map1 = new Map([...map0].filter(([k,v])=>k < 3));
const map2 = new Map([...map0].map(([k,v])=>[k*2,'_'+v]))
复制代码
5、WeakMap和Map的区别
- 只接受对象作为键名(null除外);
- WeakMap的键名所指的对象,是弱引用,即不会被计入垃圾回收机制;
(也就是说一旦不需要了,WeakMap里面的键名对象和所对应的键值对就会自动消失,不用手动删除)
(注意:弱引用的只是键名,而不是键值,键值依然是正常引用)
-
WeakMap的专用场合:
-
它的键所对应的对象,可能会在未来消失。
-
WeakMap结构有助于防止内存泄漏。
在API上的区别:
-
没有遍历操作,即没有keys()、values()、entries()方法,也没有size属性;
-
无法清空,即不支持clear()方法,因此WeakMap只有set( )、get( )、has( )、delete( )方法;
学习资料: