js-- ES6 新增 Set 和 Map ( WeakSet 和 WeakMap) 相关知识点总结
前言
前端开发语言 JavaScript 不像一些后端语言,集合数据类型只有数组类型,尽管数组也是通过键值对存储在内存中,且数组经常被当作队列和栈数据解构来使用,但是当遇到特殊情况的时候,比如要求键的索引是非数值类型的时候呢,用数组处理就变得十分麻烦,为了弥补这些缺点,ES6 引入了 Set 和 Map 这两种集合类型。本文就来总结一下这两种类型的具体使用方法。
正文
1.Set类型
(1)初始化和创建,通过构造函数。
// 创建set方法 let myset = new Set() console.log(myset); // 也可以使用数组来初始化一个集合set let iset = new Set([0.0, 1, 2, 3, 0, 2, 3]) console.log(iset);//把相等值合并
上面的代码通过构造函数来创建Set集合,同时也可以通过一个数组来初始化一个 Set 集合,由于集合中元素的唯一性,所以 iset 中元素去除了重复的数据。
(2)添加元素,通过 add()方法
// 创建set let myset = new Set() // 添加元素 myset.add("5") myset.add(5) console.log(myset);//{5,"5"} console.log(myset.size);//2 myset.add(-0) myset.add(+0) console.log(myset);//{5,"5",0} console.log(myset.size);//3
上面的代码通过add()给创建的Set集合添加元素,需要注意,数值的 5 和字符串的 5 会被当作不同的元素保存,而数值的 +0 和 -0 会被当作0保存。
(3)移除元素,通过 delete() 部分移除和 clear()全部移除。
let removeSet = new Set() removeSet.add(1) removeSet.add(2) removeSet.add(3) removeSet.delete(1) console.log(removeSet);//{2,3} removeSet.clear() console.log(removeSet);//{}
上面的代码通过 delete() 方法移除Set中的部分项,通过 clear() 移除集合的全部元素。
(4)判断元素是否存在,通过has()判断。
var hasset = new Set() hasset.add(1) console.log(hasset.has(1));//true hasset.delete(1) console.log(hasset.has(1));//false
上面的代码添加元素1后,通过has判断集合是否存在入参元素,若存在则返回 true,否则返回 false。
(5)Set元素遍历
var set = new Set() set.add(1) set.add(2) set.add(3) set.forEach((v,k,set)=>{ console.log(`v:${v}==K:${k}`); console.log("set",set); })
上面的代码需要注意,Set 通过 forEach 遍历时候,传入的函数接收三个参数,其中分别代表:Set中当前的位置的值,与第一个参数相同的值,目标 set 自身。
(6)使用Set实现数组去重
var arrSet = new Set([0,1,2,0,1,2,1,1,]), arr = [...arrSet]; console.log(arr);//[0,1,2]
上面的代码再初始化 set 的时候传入一个数组,arrSet 这个集合有元素的唯一性,把重复的项合并,然后通过剩余运算符赋值给数组,最终实现了数组的去重。
2.WeakSet类型
由于set 类型存储对象引用的方式,对象存储在 Set 的一个实例中时,实际上相当于把对象存储再变量中。只要对于 Set 实例的引用仍然存在,所存储的对象就无法被垃圾回收机制回收,从而无法释放内存。如下面的代码:
var myset = new Set() var key = {}; myset.add(key); console.log(myset.size); // 1 console.log(myset);//[{}] // 取消原始引用 key = null; console.log(myset.size); // 1 // 重新获得原始引用 key = [...myset][0]; console.log(key);//{}
上面的代码,首先创建一个Set 集合,然后添加一个空对象,但是key变量置空后取消了对空对象的引用,Set 集合的第一项仍然保持对空对象的引用,这就阻止了 js 引擎对空对象的回收。在实际开发中,遇到 Set 内部对 key 变量值的引用要随key的引用消失而消失怎么办呢?这就产生了 WeakSet 这一集合类型,该类型值允许存储对象的弱引用,而不能储存基本类型的值,对象的弱引用在它自己成为对象的唯一引用时,不回阻止垃圾回收。
需要知道 WeakSet也具有了Set同样的方法,除此之外做出了一定扩展而已。
var set = new WeakSet(), key = {}; // 将对象加入 set set.add(key); console.log(set.has(key)); // true key = null console.log(set.has(key)); // false
3.Map类型
map 类型是键值对的有序列表,而键和值可以是任意类型,键的比较可以使用 Object.is() ,因此数字型的 5 和字符串类型的 “5” 可以当作不同的键名。
(1)初始化和创建,通过构造函数。
//构造函数 var map = new Map() console.log(map); //也可以使用数组来初始化一个map var mapData = new Map([["name", "Nicholas"], ["age", '25']]); console.log(mapData);
上面的代码通过构造函数来创建 map ,同时也可以通过一个数组来初始化一个 map。打印结果如下:
(2)添加元素,通过 set()方法
var map = new Map() map.set("name", "xiaoming")//set方法传入键值对 let key = { age: "18" } map.set(key, "ageValue")//对象作为键名 console.log(map);
map中存放键值对类型的数据,区别于普通的键值对对象,它的键可以是任意类型,包括对象作为键名。打印如下:
(3)通过键来查询对应的值,通过 get()方法。
var map = new Map() map.set("name", "xiaoming") let key = { age: "18" } map.set(key, "ageValue") console.log(map.get('name'));//xiaoming console.log(map.get(key));//ageValue
map通过get()方法来获取指定键对应的值,入参为指定的键名,键名可以是任意类型。
(4)判断指定键是否在map中,通过 has()来 判断,入参为指定键名,存在返回 true,否则返回 false ;
删除指定键名以及对应的值,通过 delete()方法实现,入参为指定键名,返回是否删除成功;
移除map中所有键和值,使得map置空,通过 clear()方法来实现,无返回值;
size属性指明map 中包含的键值对个数。
var map = new Map() map.set("name", "xiaoming") let key = { age: "18" } map.set(key, "ageValue") console.log(map.size);//2 console.log(map.has("name"));//true console.log(map.delete("name"));//true console.log(map.size);//1 console.log(map.clear());//undefined console.log(map.size);//0
(5)map遍历
let mapData = new Map([["name", "Nicholas"], ["age", '25']]); mapData.forEach((value,key,ownerMap)=>{ console.log(value,"===",key); console.log(ownerMap); })
map 的通过 forEach 遍历的时候,传入函数接收三个参数,其中分别代表:map 中当前的位置的值,与第一个参数相同的值,目标 map 自身。打印结果如下:
4.WeakMap类型
WeakMap 是存储对象弱引用的方式,在 WeakMap 中,所有的键必须是对象,而且这些对象都是弱引用。
var wmap = new WeakMap() // wmap.set(1,2)//报错:TypeError: Invalid value used as weak map key var key = new Array(5) wmap.set(key, "aaa"); console.log(wmap);//WeakMap{Array(5)=>"aaa"} wmap.delete(key); console.log(wmap);//WeakMap{}
写在最后
以上就是本文的全部内容,希望给读者带来些许的帮助和进步,方便的话点个关注,小白的成长之路会持续更新一些工作中常见的问题和技术点。