9

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));

我的印象是,对于weak map,从键到值的引用是的,所以如果对值的唯一引用是键,那么就不能再访问值了。

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

4

4 回答 4

17

薄弱的部分是关于键,而不是值。从目前的草案:

WeakMap 旨在提供一种机制,以一种不会“泄漏”内存资源的方式将状态与对象动态关联,如果在没有 WeakMap 的情况下,该对象将变得不可访问并受到实现的垃圾收集机制的资源回收的影响.

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

另一方面,只要 DOM 元素存在,您就不会希望数据被删除,因为在弱映射之外没有其他对它的引用。

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

于 2013-07-09T11:28:06.683 回答
12

那么为什么该值'fish cans'仍然可以访问而不是垃圾收集呢?变量 rubbish 不再引用它,并且从 key to 的引用'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
于 2013-07-09T11:27:58.897 回答
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(),虽然变量 key 丢失了引用,但仍然可以检索到“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的对象键丢失了它的引用,这个键和值也会被垃圾回收(因为逻辑上不可访问)。这种方式可以防止内存泄漏。

如果Map的对象键丢失了它的引用,则该键和值将仍然可用,直到您删除或清除。所以在开发过程中需要注意内存泄漏

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

于 2015-03-25T05:49:49.483 回答
0

我添加这个答案来解决/澄清以下几点:

变量 ' ' 的初始值rubbish从未改变过;您所做的rubbish = 'empty bottle';只是将别名 rubbish与不同的值相关联。因此,即使在rubbish = 'empty bottle';执行之后,weakMap带有键 ' ' 的条目key仍然具有与其关联的值,该值引用 的原始值rubbish

然后要使值失去与键的关联,您应该更改键变量的值(如@Bergi 的回答中已经指出的那样)。

注意key.push("whatever");不等于改变。但是,key = [];再次重复会做得很好key = null;。通常,任何重新分配都将构成所需的更改。

于 2015-08-10T11:16:34.247 回答