了解弱地图

时间:2013-07-09 10:18:24

标签: javascript ecmascript-6 weakmap

ECMAScript 6引入了弱映射,可在Node.JS v0.11.3中使用--harmony标志。请考虑以下事项。

let weakMap = WeakMap();
let key = [];
let rubbish = 'fish cans';

weakMap.set(key, rubbish);
rubbish = 'empty bottle';

// Prints "fish cans"
console.log(weakMap.get(key));

我的印象是,对于弱地图,从键到值的引用是,因此如果对该值的唯一引用是键,则该值不能更长时间访问。

为什么值'fish cans'仍然可以访问而不是垃圾回收?变量rubbish不再引用它,从key'fish cans'的引用是,即从垃圾收集器的角度来看是不存在的。我错过了什么?

4 个答案:

答案 0 :(得分:17)

弱点是关键,而不是价值。从目前的草案:

  

WeakMap旨在提供一种机制,用于以不泄漏内存资源的方式动态关联状态与对象,如果在没有WeakMap的情况下,该对象无法访问并且受到实现的资源回收的影响垃圾收集机制。

假设您有一个DOM元素,并希望将一些数据与它相关联,并使用WeakMap来表示:weakMap.set(domElement, data);。删除DOM元素后,弱映射中的条目也会被删除。

另一方面,只要DOM元素存在,就不会想要删除数据,只是因为在弱映射之外没有其它引用。

除此之外'fish cans'是一种原始类型,因此不受垃圾收集的影响。

答案 1 :(得分:12)

  

为什么值'fish cans'仍然可以访问而不是垃圾回收?变量垃圾不再引用它,并且从密钥到'fish cans'的引用很弱,即从垃圾收集器的角度来看是不存在的。我错过了什么?

变量rubbish永远不是需要引用变量的变量。只要未收集密钥,从密钥到值的关联(引用)仍然存在。 GC无法看到的弱引用是从映射到键/值对的那个(将使映射可枚举的那个)。然而,您的key仍然存在,您可以在地图中获取为其存储的每个值:

var map = WeakMap(),
    key = [];

map.set(key, 'fish cans');
console.log(map.get(key)); // Prints "fish cans"

为了证明这个弱点,你必须使用以下内容:

var map = WeakMap(),
    key = [];

map.set(key, 'fish cans');
// map.size == 1
key = null;
// map.size == 0 - the fish cans got garbage-collected together with the key
map.get(???) // impossible now

答案 2 :(得分:0)

我也试图理解这一点。我觉得这段话说的是:

var key={a:1};
var wm=new WeakMap();


wm.set(key,"value");
wm.get(key); //you can get "value";

key=undefined;
console.log(wm.get(key));//error.original key have no longer existed. so "value" is not longer existed as well.

由于WeakMap无法检索密钥,因此您无法获得"值"更多。

如果我们使用Map(),由于有keys(),entries(),虽然变量键丢失了引用," value"仍然可以检索。

var key={a:1};
var m=new Map();


m.set(key,"value");
console.log(m.keys().next());; //you can get "value";

key=undefined;
console.log(m.get(m.keys().next().value));//you can get "value";

<强>结论:

如果 WeakMap 的对象键丢失了它的引用,那么这个键和值也将被垃圾收集(因为逻辑上不可访问)。这种方式可以防止内存泄漏。

如果地图的对象键丢失了其引用,则在您删除或清除之前,此键和值仍然可用。因此,您需要了解开发期间的内存泄漏

只需找到有关了解weakmap及其用例的链接: http://ilikekillnerds.com/2015/02/what-are-weakmaps-in-es6/

答案 3 :(得分:0)

我添加此答案以解决/澄清以下几点:

变量&#39; <div ng-app=""> <p>Name: <input type="text" ng-model="name"> </p> <p>{{name}}</p> <div ng-if="name==4">You entered four. This is a relevant message to four</div> </div> &#39;的初始值从未发生变异;您在rubbish上所做的就是将别名 rubbish = 'empty bottle';与其他值相关联。因此,即使在rubbish执行后,rubbish = 'empty bottle';条目带有键&#39; weakMap&#39}。仍然有一个与之关联的值,它引用key的原始值。

然后,为了使该值失去与键的关联,您应该更改键变量的值(如@ Bergi的回答中所述)。

请注意,rubbish不等于更改。但是,key.push("whatever");再次重复会与key = [];一样重复。通常,任何重新分配都将达到预期的变化。