Javascript 如何在ES5中实现弱映射?
有人问同样的问题,但我无法找到公认的答案 有问题的库似乎使用Javascript 如何在ES5中实现弱映射?,javascript,weakmap,Javascript,Weakmap,有人问同样的问题,但我无法找到公认的答案 有问题的库似乎使用Object.defineProperty添加对要存储的对象的引用(尽管是通过另一个对象间接地) 但是。。。当然这意味着由于这个链接,对象不能被垃圾收集 我错过了什么 真的有可能创建一个对象并将其存储在某个地方,而不维护垃圾收集器可以注意到的引用吗?(ES2015之前) 公认的答案是: 我花了一段时间摸索代码,但后来它击中了我:钥匙 本身用于存储对值的引用 例如,它将若干层设置为一组 defProp(obj,globalID,{valu
Object.defineProperty
添加对要存储的对象的引用(尽管是通过另一个对象间接地)
但是。。。当然这意味着由于这个链接,对象不能被垃圾收集
我错过了什么
真的有可能创建一个对象并将其存储在某个地方,而不维护垃圾收集器可以注意到的引用吗?(ES2015之前)
公认的答案是:
我花了一段时间摸索代码,但后来它击中了我:钥匙
本身用于存储对值的引用
例如,它将若干层设置为一组
defProp(obj,globalID,{value:store});defProp去了哪里
定义为Object.defineProperty,obj是键,globalID是
guid和store是包含该值的存储对象
然后在get中,它使用
obj[globalID]
这很聪明。WeakMap实际上不包含引用
对于任何事情(不管是弱小的还是其他的)——它只是建立了一个去哪里的策略
秘密储存价值。Object.defineProperty的使用意味着
您不会意外发现存储的价值--您必须知道
这是一个神奇的向导
因为键直接引用值(而WeakMap不引用)
引用它),当所有对该键的引用都消失时,它将获得GCD
像平常一样
当然这意味着由于这个链接,对象不能被垃圾收集
对
我错过了什么
没什么。也许这正是我们想要的行为
正如答案所解释的,“WeakMap实际上并不包含对任何东西的引用(弱的或其他的)”,“当所有对键的引用都消失时,它会像正常情况一样得到gcd。”所讨论的库中的代码是复杂的。但基于另一个更清晰的弱映射实现,我有以下几点 弱映射包含对键及其关联值的弱引用。这意味着WeakMap不会以任何方式影响对key对象或value对象的垃圾收集 在ES5中实现这一点的一种方法是,在将密钥“添加”到映射时,将其添加到所使用的密钥中(如果需要,则隐藏),然后不执行任何其他操作(即不要将密钥添加到数组中,或者确实对其执行任何操作)。在这种情况下,除了键本身之外,没有其他东西是指键的 因此,AFAICT WeakMap的API有限。例如,您不能枚举WeakMap中的项,因为它不包含对其内容的引用 请注意,WeakMap中的键不能是基元(字符串、数字、未定义、null、符号、布尔值) 使用
has
或get
时,只需在作为密钥提供的对象上查找secret属性即可
如果存在,则WeakMap“包含”或“拥有”它;否则就不行了
对于get
,secret属性可以包含对与key对象关联的值的引用,同样,WeakMap中没有对key对象或value对象的引用
我想。当然键引用了该值,否则您无法查找它。直到键被释放,才会对该值进行垃圾收集。弱映射的要点是,映射对象对键或值都没有引用……但用于存储值的任何数据结构都会保持链接。如果这个对象从来没有被GC'd,那么它就不是很“弱”?我不确定你在那里期望什么。允许观察GC的不是弱引用。
WeakMap
中的“弱”仅与映射到键和值的链接有关。在ES2015 WeakMap中,我可以向其添加对象,取消对该对象的所有其他引用,并且该对象将符合GC的条件。在这个库中,我可以将一个对象添加到它的“weakmap”中,并取消对该对象的所有引用,直到我深入挖掘库用于存储该对象的数据结构,并取消其中的引用,它才会被GC。从而否定了图书馆的观点。我肯定我遗漏了什么。@BenAston是的,看起来你还没有完全理解库的设计。“键直接引用值,而WeakMap不引用它”。地图中没有“库使用的数据结构”。WeakMap也没有强烈引用该值。对整个键值对的引用很弱。