Map

Map是一组键值对的结构,具有极快的查找速度。

 

一、构造函数不同

let map = new Map();
let weakmap = new WeakMap();

二、内置函数不同

  • Map的API有:

(1) Map.prototype.clear()
(2) Map.prototype.delete()
(3) Map.prototype.entries()
(4) Map.prototype.forEach()
(5) Map.prototype.get()
(6) Map.prototype.has()
(7) Map.prototype.keys()
(8) Map.prototype.set()
(9) Map.prototype.values()
(10) Map.prototype[@@iterator]()

(1) WeakMap.prototype.delete()
(2) WeakMap.prototype.get()
(3) WeakMap.prototype.has()
(4) WeakMap.prototype.set()

可以看出weakMap api少了clear, entries,forEach,keys,values,以及获取iterator对象的方法,另外weakMap还没有size属性,无法获取内部存了多少个映射。

三、GC垃圾回收

let a = {x: 12};
let b = {y: 13};

let map = new Map();
let weakMap = new WeakMap();
map.set(a, '14');
weakMap.set(b, '15');

a = null;
b = null; // 设置为null提醒垃圾回收可以回收了。
当把a, b都设置成null之后,GC会回收weakMap中的b对象对应的键值对(这里的意思是键和值都回收),也就是{ y: 13}这个对象会被回收,'14'这个常量也会被清除。但是不会回收Map中a对象对应的键值对,也就是{x: 12}这个对象并不会回收。
WeakMap中值被回收,是因为键被回收了
let a = {x: 12};
let b = {y: 15};
let weakMap = new WeakMap();
weakMap.set(a, b);
console.log(weakMap.get(a));
b = null; // 这样做不会影响weakMap的存储
console.log(weakMap.get(a));

如果是WeakMap的话,targetobj存在的就是弱引用关系,当下一次垃圾回收机制执行时,这块内存就会被释放掉。设想一下,如果我们要拷贝的对象非常庞大时,使用Map会对内存造成非常大的额外消耗,而且我们需要手动清除Map的属性才能释放这块内存,而WeakMap会帮我们巧妙化解这个问题。