EcmaScript5 中的 WeakMap 实现?
Posted
技术标签:
【中文标题】EcmaScript5 中的 WeakMap 实现?【英文标题】:WeakMap implementation in EcmaScript5? 【发布时间】:2013-04-28 06:36:48 【问题描述】:我遇到了一个在 ES5 中实现跨浏览器 WeakMap 的 javascript library。 (WeakMap 计划用于 ES6。)
如果没有 JavaScript 语言本身的支持,这怎么可能工作?
编辑:为了清楚起见,我指的是Weak地图,而不是常规地图。我使用 Chrome 的分析器测试了这个项目,并且密钥不是由强引用持有的。他们无需从 WeakMap 中删除即可获得 GC。
【问题讨论】:
考虑研究源码。 @squint 它正在做一些相当深入的事情——我无法弄清楚它是如何没有对键进行强引用的。例如,它不使用数组。 WeakMaps 是一个 ES6 功能,它允许您将数据与对象相关联,但当对象或 WeakMap 实例本身被垃圾收集时,仍然让该数据被垃圾收集。如果没有语言支持,就不可能做到这两点。大多数 WeakMap 垫片忽略了当 WeakMap 实例本身被 GC 时让数据被 GC 的部分。 【参考方案1】:我花了一些时间来摸索代码,但后来我突然想到了:键本身用于存储对值的引用。
例如,将几层放入set
就可以了
defProp(obj, globalID, value: store );
其中defProp
已定义为Object.defineProperty
,obj
是键,globalID
是 guid,store
是包含值的存储对象。
然后在get
中查找值
obj[globalID];
这很聪明。 WeakMap 实际上并不包含对任何东西(弱或其他)的引用——它只是设置了一个秘密存储值的策略。使用Object.defineProperty
意味着您不会意外发现值存储——您必须知道魔法指南才能查找它。
由于键直接引用值(而 WeakMap 不引用它),当所有对键的引用都消失时,它会像往常一样被 GC。
【讨论】:
如果obj
是WeakMap键,globalID
是在obj
上定义的,我想知道为什么globalID
在使用Object.getOwnPropertyNames()
时没有出现。
我也有同样的疑惑;太糟糕了,lib 远远落后于它自己,以至于几乎无法阅读。必须有一个更简单的解释......
想通了:lib 作弊:它重新定义了 Object.getOwnPropertyNames()。 boo 用于踩踏现有的原生函数。
它只重新定义 getOwnPropertyNames
以实现 WeakMap。它不会破坏任何东西,并且getOwnPropertyNames
' 功能保持不变。该环境与 ES5 完全向后兼容,并与 ES6 WeakMaps 完全向前兼容。这真是个好主意。我在Secrets 中使用它达到了同样的效果。
垫片不提供 WeakMap 的主要属性之一:该值被弱保存。这个 shim 在键和值之间创建了一个强引用......类似于将值设置为键对象的属性。以上是关于EcmaScript5 中的 WeakMap 实现?的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript 中的 Map, Set, WeakMap, WeakSet