1、Map是为了解决对象中的key只能为字符串的缺陷
//基本的对象constobj={'name':'张飞',,'age':18}//Mapletm=newMap()a.set(obj,1)我们的Map是可以解决对象的key不能为对象的缺陷,但是又随之而来了一个缺点:耗费内存,强引用
2、什么是强/弱引用
就是创建引用之后,无法被垃圾资源回收机制进行回收的,就是强引用。强到你设置了null,也分不开。
constrefence=[[obj:1]]现在我们把obj赋值为null,但是我们的[obj:1]是一个数组,也是一个引用的类型,把obj赋值为了空,但是refence和数组之前还是存在引用的关系,所以无法分开。
因为我们都知道为了防止内存泄漏,通常把一个对象使用完之后设置为null,那如果是上面这种情况,就算你设为null也无法垃圾回收了。
3、WeakMap和Map的区别
ES6考虑到了这一点,推出了:WeakMap。它对于值的引用都是不计入垃圾回收机制的,所以名字里面才会有一个"Weak",表示这是弱引用(对对象的弱引用是指当该对象应该被GC回收时不会阻止GC的回收行为)。
(1)强/弱引用的区别:Map强,WeakMap弱
(2)WeakMap只接受对象为key值
在实现完美的深拷贝中,我们使用WeakMap代替Map的使用来解决循环引用的问题,进行优化。
Map相对于WeakMap:
(1)Map的键可以是任意类型,WeakMap只接受对象作为键(null除外),不接受其他类型的值作为键
(2)Map的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键;WeakMap的键是弱引用,键所指向的对象可以被垃圾回收,此时键是无效的
(3)Map可以被遍历,WeakMap不能被遍历
只要外部的引用消失,WeakMap内部的引用,就会自动被垃圾回收清除。由此可见,有了它的帮助,解决内存泄漏就会简单很多。
MDN上说WeakMap对象是一组键/值对的集合,其中的键是弱引用的。其键必须是对象,而值可以是任意的。
注意,WeakMap弱引用的只是键名,而不是键值。键值依然是正常引用。
WeakMap中,每个键对自己所引用对象的引用都是弱引用,在没有其他引用和该键引用同一对象,这个对象将会被垃圾回收(相应的key则变成无效的),所以,WeakMap的key是不可枚举的。
语法也很简单:constwp=newWeakMap();
在使用的过程中我们需要注意WeakMap的key只能是Object类型
//创建一个在每个实例中存储私有变量的对象constinternal=obj=>{if(!wp.has(obj)){wp.set(obj,{});}returnwp.get(obj);}classShape{constructor(width,height){internal(this).width=width;internal(this).height=height;}getarea(){returninternal(this).width*internal(this).height;}}constsquare=newShape(10,10);console.log(square.area);//100console.log(map.get(square));//根据对象获得返回值{height:100,width:100}上面代码示例看到我们通过internal(this)然后去设置其属性。然后可以通过map.get(square)获取到square对象。
WeakMap好处是在遍历属性时或者在执行JSON.stringify时不会展示出实例的私有属性,但它依赖于一个放在类外面的可以访问和操作的WeakMap变量,WeakMap每个键对自己所引用对象的引用是"弱引用",这意味着如果没有其他引用和该键引用同一个对象,这个对象将会被当作垃圾回收,从而得到不确定的结果。
就是说WeakMap里面的数据可能被垃圾回收机制清除或者一个对应在WeakMap结构的对象在外部被删除时,上述情况所对应的WeakMap的键值对也会被自动被移除。因此,如果你想要这种类型对象的key值的列表,你应该使用Map。
常用方法:
(1)WeakMap.prototype.delete(key):移除key的关联对象。执行后WeakMap.prototype.has(key)返回false
(2)WeakMap.prototype.get(key):返回key关联对象,或者undefined(没有key关联对象时)。
(3)WeakMap.prototype.has(key):根据是否有key关联对象返回一个Boolean值。
(4)WeakMap.prototype.set(key,value)在WeakMap中设置一组key关联对象,返回这个WeakMap对象。
(5)WeakMap.prototype.clear()从WeakMap中移除所有的key/value。(参考WeakMap)
除了WeakMap还有WeakSet都是弱引用,可以被垃圾回收机制回收,可以用来保存DOM节点,不容易造成内存泄漏。