什么是ES6地图和WeakMap之间的区别?(What's the difference b

2019-07-23 02:31发布

看这个和这个 ,好像地图和WeakMaps之间的唯一区别MDN页是WeakMaps丢失的“大小”属性。 但是,这是真的吗? 什么是它们之间的区别?

Answer 1:

从非常相同的页面,部分“ 为什么地图?”

的经验的JavaScript程序员会注意到这个API可能在JavaScript来实现与由所述4种API方法共享两个数组(一个用于键,一个用于值)。 这样的实现有两个主要的不便。 第一个是一个为O​​(n)的搜索(n是密钥的地图数)。 第二个是一个内存泄漏问题。 与手工编写的地图, 按键的排列会继续引用主要对象,防止它们被垃圾收集。 在本地WeakMaps,重点对象的引用举行的“弱”,这意味着它们不妨碍垃圾收集的情况下,就没有其他的参照对象。

因为引用是弱,WeakMap键是不可枚举的(即有没有方法让你的密钥列表)。 如果他们是,名单将取决于垃圾收集的状态,引入非确定性。

[这就是为什么他们没有size属性以及]

如果你想拥有的密钥列表,你应该自己维护。 还有一个ECMAScript的建议 ,旨在引入简单套和地图这不会使用弱引用,并会枚举。

-这将是“正常”的Map小号 。 在MDN没有提及,但在和谐的提案 ,这些也有itemskeysvalues生成方法和实现Iterator接口 。



Answer 2:

他们都不同的表现时它们的键/值引用的对象被删除。 让我们下面的例子的代码:

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}从存储器。 但在“地图”的情况下,垃圾收集器没有从“地图”删除指针,也不会删除{x: 12}从存储器。

摘要:WeakMap允许垃圾收集器来完成其任务,但没有地图。

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



Answer 3:

也许接下来的解释将是别人更加清晰。

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从存储钥匙我们仍然可以在地图内访问它。 与此同时除去k2密钥WeakMap从删除该wm以及通过引用。

这就是为什么WeakMap具有不可枚举的方法,如的forEach,因为作为WeakMap键列表中没有这样的事情,他们只是到另一个对象的引用。



Answer 4:

另一个区别(来源: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap ):

WeakMaps的密钥只对象的类型。 原始数据类型作为键不准(例如一个符号不能是WeakMap键)。

也不能字符串,数字,或布尔用作WeakMap键。 一个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


Answer 5:

WeapMap在JavaScript中不持有任何键或值,它只是使用一个唯一的ID操纵的键值,并定义属性密钥对象。

因为它定义属性key由方法Object.definePropert()键不能为原始类型。

也因为WeapMap不包含实际键值对,我们不能得到weakmap的length属性。

并且还操纵值被分配回钥匙,垃圾收集器可以轻松地收集,如果它没有用关键。

实施示例代码。

if(typeof WeapMap != undefined){
return;
} 
(function(){
   var WeapMap = function(){
      this.__id = '__weakmap__';
   }

   weakmap.set = function(key,value){
       var pVal = key[this.__id];
        if(pVal && pVal[0] == key){
           pVal[1]=value;
       }else{
          Object.defineProperty(key, this.__id, {value:[key,value]});
          return this;
        }
   }

window.WeakMap = WeakMap;
})();

参考实施



文章来源: What's the difference between ES6 Map and WeakMap?