是否可以在 JavaScript 中创建“弱引用”?

IT技术 javascript weak-references
2021-03-10 12:17:52

JavaScript 中有什么方法可以创建对另一个对象的“弱引用”?这是描述什么是弱引用的 wiki 页面。 这是另一篇用 Java 描述它们的文章。谁能想出一种在 JavaScript 中实现这种行为的方法?

6个回答

更新:自 2020 年 7 月以来,一些实现(Chrome、Edge、Firefox 和 Node.js)已支持WeakRefs 提案中WeakRef定义的 s,该提案是截至 2020 年 12 月 16 日的“第 3 阶段草案”。

JavaScript 中没有对弱引用的语言支持。您可以使用手动引用计数来滚动自己的引用计数,但不是特别顺利。您不能创建代理包装器对象,因为在 JavaScript 中对象永远不知道它们何时将被垃圾收集。

因此,您的“弱引用”成为简单查找中的键(例如整数),使用添加引用和删除引用方法,并且当不再有手动跟踪的引用时,可以删除条目,从而保留将来的查找该键返回空值。

这并不是真正的弱引用,但它可以解决一些相同的问题。当 DOM 节点或事件处理程序与与其关联的对象(例如闭包)之间存在引用循环时,它通常在复杂的 Web 应用程序中完成,以防止浏览器(通常是 IE,尤其是旧版本)的内存泄漏。在这些情况下,甚至可能不需要完整的引用计数方案。

对于 ES6,这个答案不再正确。请参阅我下面的回答stackoverflow.com/a/28567560/745190
2021-04-18 12:17:52
它仍然是正确的,因为 ES6 WeakMaps 不是真正的弱引用。WeakMaps 只接受对象作为键,并且对这些对象的引用被弱持有。参见stackoverflow.com/questions/32397729/...
2021-05-01 12:17:52
我写了一个类来模拟弱映射并将其发布在这里:stackoverflow.com/a/47017206/491553
2021-05-05 12:17:52
我没有仔细检查(或使用)代码,但 es-lab 有一个提供基本WeakMap 仿真的脚本Aurora 6 (Mozilla) 有一个非标准的WeakMap 实现
2021-05-07 12:17:52

在 NodeJS 上运行 JS 时,可以考虑https://github.com/TooTallNate/node-weak

更新:2019 年 9 月

目前还不可能使用弱引用,但很可能很快就会成为可能,因为JavaScript 中的WeakRefs正在开发中。详情如下。

提议

现在处于第 3 阶段的提案,这意味着它具有完整的规范,进一步的改进将需要来自实现和用户的反馈。

WeakRef提案涵盖的功能两大新作品:

  • 使用WeakRef 类创建对对象的弱引用
  • 在对象被垃圾收集后运行用户定义的终结器,使用FinalizationGroup 类

用例

一个主要用途为弱引用是实现高速缓存或映射举办大型的物体,在它的希望,因为它出现在高速缓存或映射一个大对象没有保持活着只。

终结是在程序执行无法访问的对象之后执行代码以进行清理。用户定义的终结器启用了几个新用例,并且可以在管理垃圾收集器不知道的资源时帮助防止内存泄漏。

来源和进一步阅读

https://github.com/tc39/proposal-weakrefs
https://v8.dev/features/weak-references

Firefox Nightly 添加了对 WeakRef 的实验性支持。这是一个使用它来创建 WeakSet 的可迭代版本的示例实现:gist.github.com/seanlinsley/bc10378fd311d75cf6b5e80394be813d
2021-04-24 12:17:52

仅供参考;JavaScript 没有,但 ActionScript 3(也是 ECMAScript)有。查看Dictionary构造函数参数

他们终于来了。尚未在浏览器中实现,但很快就会实现。

https://v8.dev/features/weak-references