如何在ES5中实施弱地图?

时间:2017-06-06 12:20:10

标签: javascript weakmap

another question有同样的问题,但我无法理解接受的答案。

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

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

我错过了什么?

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

接受的答案:

  

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

     

例如,设置它的几个层

     

defProp(obj,globalID,{value:store}); defProp一直在哪里   定义为Object.defineProperty,obj是键,globalID是a   guid和store是一个包含值的存储对象。

     

然后向下看,用

查找值      

OBJ [globalID];

     

这很聪明。 WeakMap实际上并不包含引用   对任何事情(弱或其他) - 它只是建立了一个政策,在哪里   秘密存储价值。 Object.defineProperty的使用意味着   你不会意外地发现价值存储 - 你必须知道   寻找它的神奇指导。

     

因为键直接引用了值(并且WeakMap没有&t; t   参考它),当对密钥的所有引用都消失后,它就会被GCed   像平常一样。

The library in question

2 个答案:

答案 0 :(得分:1)

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

  

我错过了什么?

无。也许这正是所期望的行为。

正如答案所解释的那样," WeakMap实际上并未包含对任何内容的引用(弱或其他)"和" 当对密钥的所有引用都消失后,它就像正常情况一样得到GC。"

答案 1 :(得分:0)

相关库中的代码是错综复杂的。但基于另一个更清晰的WeakMap实现,我有以下内容......

WeakMap为密钥和与之关联的值保存弱引用。这意味着WeakMap不会以任何方式影响密钥对象或值对象的垃圾收集。

在ES5中实现这一目标的方法是在向地图“添加”时使用的键添加(如果需要,隐藏)属性,然后不执行任何操作(即不将键添加到数组或确实对它做任何事情)。这样,没有任何东西指的是除了它自己以外的钥匙。

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

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

使用hasget时,您只需在提供的对象上查找密钥属性即可。

如果存在,则WeakMap“包含”或“具有”它;否则它没有。

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

我想。