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 像平常一样。
答案 0 :(得分:1)
肯定会因为这个链接而意味着对象不能被垃圾收集?
是
我错过了什么?
无。也许这正是所期望的行为。
正如答案所解释的那样," WeakMap实际上并未包含对任何内容的引用(弱或其他)"和" 当对密钥的所有引用都消失后,它就像正常情况一样得到GC。"
答案 1 :(得分:0)
相关库中的代码是错综复杂的。但基于另一个更清晰的WeakMap实现,我有以下内容......
WeakMap为密钥和与之关联的值保存弱引用。这意味着WeakMap不会以任何方式影响密钥对象或值对象的垃圾收集。
在ES5中实现这一目标的方法是在向地图“添加”时使用的键添加(如果需要,隐藏)属性,然后不执行任何操作(即不将键添加到数组或确实对它做任何事情)。这样,没有任何东西指的是除了它自己以外的钥匙。
由于这个原因,AFAICT WeakMap的API有限。例如,您不能枚举WeakMap中的项目,因为它不包含对其内容的引用!
请注意,WeakMap中的键不能是原语(字符串,数字,未定义,null,符号,布尔值)。
使用has
或get
时,您只需在提供的对象上查找密钥属性即可。
如果存在,则WeakMap“包含”或“具有”它;否则它没有。
对于get
,secret属性可以包含对与key对象关联的值的引用,同样没有WeakMap对key对象或value对象的引用。
我想。