ES6 Map和WeakMap有什么区别?

看起来这和这个 MDN页面似乎像地图和WeakMaps的唯一区别是WeakMaps的缺less“大小”属性。 但这是真的吗? 他们之间有什么区别?

从相同的页面, 为什么地图?

有经验的JavaScript程序员会注意到,这个API可以在JavaScript中用4个API方法共享的两个数组(一个用于键,一个用于值)共享。 这样的实施会有两个主要的不便。 第一个是O(n)search(n是地图中的键的数量)。 第二个是内存泄漏问题。 使用手动编写的地图, 键的数组将保持对关键对象的引用,防止垃圾收集。 在本地WeakMaps中,对关键对象的引用是“微弱的” ,这意味着它们不会阻止垃圾回收,以防其他对象引用。

由于引用弱,WeakMap键是不可枚举的(即没有方法给你一个键的列表)。 如果是的话,清单将取决于垃圾收集的状态,引入非确定性。

[这就是为什么他们也没有size财产]

如果你想有一个键列表,你应该自己维护它。 还有一个ECMAScript提案旨在介绍简单的集合和映射,不会使用弱引用,并且可以枚举。

– 这将是“正常”的Map 。 在MDN中没有提到,但是在和谐提案中 ,那些itemskeysvalues生成器方法也实现了Iterator接口 。

当它们的键/值引用的对象被删除时,它们的行为都不同。 让我们拿下面的例子代码:

 var map = new Map(); var weakmap = new WeakMap(); (function(){ var a = {x: 12}; var b = {y: 12}; map.set(a, 1); weakmap.set(b, 2); })() 

上面的IIFE被执行,我们不能再引用{x: 12}{y: 12}了。 垃圾收集器继续,并从“WeakMap”中删除键b指针,并从内存中删除{y: 12} 。 但是在“Map”的情况下,垃圾收集器不会从“Map”中删除指针,也不会从内存中删除{x: 12}

总结:WeakMap允许垃圾回收器完成它的任务,但不能执行Map。

参考文献: http : //qnimate.com/difference-between-map-and-weakmap-in-javascript/

也许下一个解释会更清楚的人。

 var k1 = {a: 1}; var k2 = {b: 2}; var map = new Map(); var wm = new WeakMap(); map.set(k1, 'k1'); wm.set(k2, 'k2'); k1 = null; map.forEach(function (val, key) { console.log(key, val); // k1 {a: 1} }); k2 = null; wm.get(k2); // undefined 

正如你所看到的,从内存中删除k1键后,我们仍然可以在地图内访问它。 同时删除WeakMap的k2键也将其从wm移除,以供参考。

这就是为什么WeakMap没有像forEach这样的可枚举的方法,因为没有WeakMap键的列表,它们只是引用另一个对象。

另一个区别:

WeakMaps的键只是Object的types。 不允许原始数据types作为键(例如,符号不能是弱映射键)。

WeakMap键也不能使用string,数字或布尔值。 Map 可以使用键的原始值。

 w = new WeakMap; w.set('a', 'b'); // Uncaught TypeError: Invalid value used as weak map key m = new Map m.set('a', 'b'); // Works