这似乎是部分 polyfill 作者误解的结果,请考虑编写错误报告。
这些方法确实保留了对对象的强引用,这是一种技术上符合要求的实现,因为程序不能仅仅因为从未观察到删除对象而认为垃圾收集器被破坏。但是,要实现这一壮举会容易得多:只需将对象存储在属性中,根本不用理会 a WeakMap
。
正如您所观察到的,我认为有些人天真地期望 aWeakMap
对values的引用很弱。在仔细阅读文档之前,我也曾经有过这样的误解。然而,这并不能解释为什么WeakMap
自 2015 年以来一直在规范中WeakRef
,而在 3 年多的时间里还没有超过提案阶段。这种幼稚的集合就像一个Map
of WeakRefs
,那么为什么该语言不也暴露一个呢?
事实是,它是不可能被模仿WeakRef
的,WeakMap
并且已经采取了仔细的设计来做到这一点(主要是它是不可枚举的)。为什么?虽然完全有可能可靠地实现这种行为,但设计组的观点是倾向于确定性和可预测性。这个简短的段落很好地总结了它,推理和一个被认为是错误设计过去决定的例子。以下两句话直接排除了类似 a 的内容WeakRef
:
这意味着您不应公开任何充当弱引用的 API,例如,一旦运行垃圾收集,属性就会变为 null。JavaScript 代码中的对象和数据生命周期应该是可预测的。
考虑到这一点,在遵循 W3C TAG 指南的实现中,不仅WeakMap
不能使用,甚至不能使用任何其他方法(应该回答你在评论中的最后一个问题),除非可能使用像这样的丑陋和不可靠的漏洞示例中提到的具体情况。除非委员会的意见发生根本变化,否则提案WeakRef
可能永远不会真正标准化。让我们希望当前版本中包含的谨慎措辞,以及对过度内存使用和其他有趣且有充分根据的用例的呼吁最终将允许此类例外。