0

还有另一个问题问同样的问题,但我无法理解接受的答案。

有问题的库似乎用于Object.defineProperty添加对要存储的对象的引用(尽管间接通过另一个对象)。

但是......当然这意味着该对象不能因为这个链接而被垃圾收集?

我错过了什么?

是否真的可以创建一个对象并将其存储在某个地方而无需维护垃圾收集器可注意到的引用?(在 ES2015 之前)

接受的答案:

我花了一些时间来摸索代码,但后来它击中了我:键本身用于存储对值的引用。

例如,将其设置为几层

defProp(obj, globalID, { value: store }); 其中 defProp 已定义为 Object.defineProperty,obj 是键,globalID 是 guid,store 是包含值的存储对象。

然后在 get 它查找值

对象[全局ID];

这是非常聪明的。WeakMap 实际上并不包含对任何东西(弱或其他)的引用——它只是设置了一个秘密存储值的策略。使用 Object.defineProperty 意味着您不会意外发现值存储——您必须知道查找它的魔法指南。

由于键直接引用值(而 WeakMap 不引用它),当所有对键的引用都消失时,它会像往常一样进行 GC。

有问题的图书馆

4

2 回答 2

1

这肯定意味着该对象不能因为这个链接而被垃圾收集吗?

是的。

我错过了什么?

没有什么。也许这正是所需的行为。

正如答案所解释的那样,“ WeakMap 实际上不包含对任何东西(弱或其他)的引用”和“当对密钥的所有引用都消失时,它会像往常一样进行 GC。

于 2017-06-06T12:26:20.980 回答
0

有问题的库中的代码很复杂。但是基于另一个更清晰的 WeakMap 实现,我有以下...

WeakMap 持有对与其关联的键和值的弱引用。这意味着 WeakMap 不会以任何方式影响键对象或值对象的垃圾收集。

在 ES5 中实现这一点的方法是在将其“添加”到地图时使用的键添加一个(如果需要,可以隐藏)属性,然后什么也不做(即不要将键添加到数组或确实做任何事情用它)。这样一来,除了它自己之外,没有任何东西涉及到密钥。

出于这个原因,AFAICT WeakMap 的 API 有限。例如,您不能枚举 WeakMap 中的项目,因为它不包含对其内容的引用!

请注意,WeakMap 中的键不能是原语(字符串、数字、未定义、空值、符号、布尔值)。

使用hasorget时,您可以简单地在作为密钥提供的对象上查找 secret 属性。

如果它存在,则 WeakMap “包含”或“拥有”它;否则它不会。

对于get,secret 属性可以包含对与键对象关联的值的引用,同样,WeakMap 没有对键对象或值对象的引用。

我认为。

于 2017-06-07T07:52:26.160 回答