看这个和这个 ,好像地图和WeakMaps之间的唯一区别MDN页是WeakMaps丢失的“大小”属性。 但是,这是真的吗? 什么是它们之间的区别?
Answer 1:
从非常相同的页面,部分“ 为什么弱地图?” :
的经验的JavaScript程序员会注意到这个API可能在JavaScript来实现与由所述4种API方法共享两个数组(一个用于键,一个用于值)。 这样的实现有两个主要的不便。 第一个是一个为O(n)的搜索(n是密钥的地图数)。 第二个是一个内存泄漏问题。 与手工编写的地图, 按键的排列会继续引用主要对象,防止它们被垃圾收集。 在本地WeakMaps,重点对象的引用举行的“弱”,这意味着它们不妨碍垃圾收集的情况下,就没有其他的参照对象。
因为引用是弱,WeakMap键是不可枚举的(即有没有方法让你的密钥列表)。 如果他们是,名单将取决于垃圾收集的状态,引入非确定性。
[这就是为什么他们没有size
属性以及]
如果你想拥有的密钥列表,你应该自己维护。 还有一个ECMAScript的建议 ,旨在引入简单套和地图这不会使用弱引用,并会枚举。
-这将是“正常”的Map
小号 。 在MDN没有提及,但在和谐的提案 ,这些也有items
, keys
和values
生成方法和实现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;
})();
参考实施