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

发布于 2024-07-08 14:33:36 字数 325 浏览 9 评论 0原文

JavaScript 有没有办法创建对另一个对象的“弱引用”? 这是描述什么是弱引用的 wiki 页面。 这是另一篇用 Java 描述它们的文章。 任何人都可以想办法吗在 JavaScript 中实现这个行为?

Is there any way in JavaScript to create a "weak reference" to another object? Here is the wiki page describing what a weak reference is. Here is another article that describes them in Java. Can anyone think of a way to implement this behavior in JavaScript?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

清风挽心 2024-07-15 14:33:37

EcmaScript 6 (ES Harmony) 有一个 WeakMap 对象。 现代浏览器对浏览器的支持非常好(最近 3 个版本的 Firefox、chrome甚至即将推出的 IE 版本也支持它)。

EcmaScript 6 (ES Harmony) has a WeakMap object. Browser support amongst modern browsers is pretty good (the last 3 versions of Firefox, chrome and even an upcoming IE version support it).

简单 2024-07-15 14:33:37

http://www.jibbering.com/faq/faq_notes/closures.html

ECMAScript 使用自动垃圾收集。 该规范没有定义细节,将其留给实现者来解决,并且已知某些实现为其垃圾收集操作赋予非常低的优先级。 但一般的想法是,如果一个对象变得不可引用(通过没有剩余的引用可供执行代码访问),它就可以用于垃圾回收,并且将在将来的某个时刻被销毁,并且它正在消耗的任何资源都会被释放并返回到系统以供重复使用。

退出执行上下文时通常会出现这种情况。 作用域链结构、激活/变量对象以及在执行上下文中创建的任何对象(包括函数对象)将不再可访问,因此将可用于垃圾回收。

这意味着没有弱者,只有不再可用的者。

http://www.jibbering.com/faq/faq_notes/closures.html

ECMAScript uses automatic garbage collection. The specification does not define the details, leaving that to the implementers to sort out, and some implementations are known to give a very low priority to their garbage collection operations. But the general idea is that if an object becomes un-referable (by having no remaining references to it left accessible to executing code) it becomes available for garbage collection and will at some future point be destroyed and any resources it is consuming freed and returned to the system for re-use.

This would normally be the case upon exiting an execution context. The scope chain structure, the Activation/Variable object and any objects created within the execution context, including function objects, would no longer be accessible and so would become available for garbage collection.

Meaning there are no weak ones only ones that no longer become available.

月牙弯弯 2024-07-15 14:33:36

更新:自 2020 年 7 月起,一些实现(Chrome、Edge、Firefox 和 Node.js)已支持 WeakRefWeakRefs 提案,截至 2020 年 12 月 16 日,这是“第 3 阶段草案”。

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

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

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

Update: Since July, 2020 some implementations (Chrome, Edge, Firefox and Node.js) has had support for WeakRefs as defined in the WeakRefs proposal, which is a "Stage 3 Draft" as of December 16, 2020.

There is no language support for weakrefs in JavaScript. You can roll your own using manual reference counting, but not especially smoothly. You can't make a proxy wrapper object, because in JavaScript objects never know when they're about to be garbage-collected.

So your ‘weak reference’ becomes a key (eg. integer) in a simple lookup, with an add-reference and remove-reference method, and when there are no manually-tracked references anymore then entry can be deleted, leaving future lookups on that key to return null.

This is not really a weakref, but it can solve some of the same problems. It's typically done in complex web applications to prevent memory leakage from browsers (typically IE, especially older versions) when there is a reference loop between a DOM Node or event handler, and an object associated with it such as a closure. In these cases a full reference-counting scheme may not even be necessary.

べ繥欢鉨o。 2024-07-15 14:33:36

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

When running JS on NodeJS, you may consider https://github.com/TooTallNate/node-weak.

冷︶言冷语的世界 2024-07-15 14:33:36

更新:2019 年 9 月

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

提案

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

WeakRef 提案包含两个主要的新功能:

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

用例

弱引用的主要用途是实现保存大对象的缓存或映射,其中不希望大对象仅因为出现在缓存中而保持活动状态或映射。

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

来源和进一步阅读

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

Update: September 2019

It is not possible to use weak references yet, but most likely soon it will be possible, as WeakRefs in JavaScript are Work In Progress. Details below.

Proposal

Proposal in now in Stage 3 which means that it has complete specification and that further refinement will require feedback from implementations and users.

The WeakRef proposal encompasses two major new pieces of functionality:

  • Creating weak references to objects with the WeakRef class
  • Running user-defined finalizers after objects are garbage-collected, with the FinalizationGroup class

Use cases

A primary use for weak references is to implement caches or mappings holding large objects, where it’s desired that a large object is not kept alive solely because it appears in a cache or mapping.

Finalization is the execution of code to clean up after an object that has become unreachable to program execution. User-defined finalizers enable several new use cases, and can help prevent memory leaks when managing resources that the garbage collector doesn't know about.

Source and further reading

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

决绝 2024-07-15 14:33:36

2021 更新

WeakRef 现已在 Chrome、Edge 和 Firefox 中实现。 仍在等待 Safari 和其他一些坚持不懈的人。

https://developer.mozilla.org/en- US/docs/Web/JavaScript/Reference/Global_Objects/WeakRef

2021 年 5 月更新
现在,它可以在 Safari 以及所有主要浏览器上使用。 往上看。

2021 Update

WeakRef is now implemented in Chrome, Edge, and Firefox. Still waiting on Safari and some other holdouts.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakRef

May 2021 Update
It's now available on Safari thus all major browsers. See above.

违心° 2024-07-15 14:33:36

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

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

Finally they are here. Not yet implemented in browsers, but soon to be.

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

南烟 2024-07-15 14:33:36

真正的弱引用,不,还没有(但浏览器制造商正在研究这个主题)。 但这里有一个关于如何模拟弱引用的想法。

您可以构建一个缓存来驱动对象。 当存储对象时,缓存会预测该对象将占用多少内存。 对于某些项目,例如存储图像,这是很容易解决的。 对于其他人来说,这会更加困难。

当您需要一个对象时,您可以向缓存请求它。 如果缓存有该对象,则返回该对象。 如果不存在,则生成、存储该项目,然后返回该项目。

当预测的内存总量达到一定水平时,通过缓存删除项目来模拟弱引用。 它将根据物品被检索的频率以及它们被取出的时间进行加权来预测哪些物品是最少使用的。 如果创建项目的代码作为闭包传递到缓存中,则还可以添加“计算”成本。 这将允许缓存保留构建或生成非常昂贵的项目。

删除算法是关键,因为如果你犯了这个错误,那么你最终可能会删除最受欢迎的项目。 这会导致糟糕的性能。

只要缓存是唯一对所存储的对象具有永久引用的对象,那么上述系统应该可以很好地替代真正的弱引用。

True weak references, no, not yet (but browser makers are looking at the subject). But here is an idea on how to simulate weak references.

You could build a cache which you drive your objects through. When an object is stored, the cache keeps a prediction of how much memory the object will take up. For some items, like storing images, this is straight forward to work out. For others this would be more difficult.

When you need an object, you then ask the cache for it. If the cache has the object, it is returned. If it is not there, then the item is generated, stored, and then returned.

The weak references are simulated by the cache removing items, when the total amount of predicted memory reaches a certain level. It will predict which items are least used based on how often they are retrieved, weighted by how long ago they were taken out. A 'calculation' cost could also be added, if the code that creates the item is passed into the cache as a closure. This would allow the cache to keep items which are very expensive to build or generate.

The deletion algorithm is key, because if you get this wrong then you could end up removing the most popular items. This would cause terrible performance.

As long as the cache is the only object with permanent references to the objects stored, then the above system should work pretty well as an alternative to true weak references.

杀手六號 2024-07-15 14:33:36

使用缓存机制来模拟弱引用,如JL235建议以上,是合理的。 如果弱引用本身存在,您将观察到如下行为:

this.val = {};
this.ref = new WeakReference(this.val);
...
this.ref.get(); // always returns val
...
this.val = null; // no more references
...
this.ref.get(); // may still return val, depending on already gc'd or not

而使用缓存,您将观察到:

this.val = {};
this.key = cache.put(this.val);
...
cache.get(this.key); // returns val, until evicted by other cache puts
...
this.val = null; // no more references
...
cache.get(this.key); // returns val, until evicted by other cache puts

作为引用的持有者,您不应该对它何时引用某个值做出任何假设,这与使用缓存

Using a caching mechanism to emulate a weak reference, as JL235 suggested above, is reasonable. If weak references would exist natively, you would observe a behavior like this:

this.val = {};
this.ref = new WeakReference(this.val);
...
this.ref.get(); // always returns val
...
this.val = null; // no more references
...
this.ref.get(); // may still return val, depending on already gc'd or not

Whereas with a cache you would observe:

this.val = {};
this.key = cache.put(this.val);
...
cache.get(this.key); // returns val, until evicted by other cache puts
...
this.val = null; // no more references
...
cache.get(this.key); // returns val, until evicted by other cache puts

As a holder of a reference, you should not make any assumptions about when it refers to a value, this is no different using a cache

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文