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'
的引用是弱,即从垃圾收集器的角度来看是不存在的。我错过了什么?
答案 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 = [];
一样重复。通常,任何重新分配都将达到预期的变化。