javascript - 什么是 ES2021 (ES12) 中的 WeakRef 和终结器

标签 javascript ecmascript-2021

我想了解 WeakRef 是什么和 Finalizers ES2021 真正简单的例子在哪里 使用它们。
我知道,WeakRef是一类。这将允许开发人员创建对对象的弱引用,以及 Finalizer 或 FinalizationRegistry允许您注册将在对象被垃圾回收时调用的回调函数

const myWeakRef = new WeakRef({
  name: 'Cache',
  size: 'unlimited'
})

// Log the value of "myWeakRef":
console.log(myWeakRef.deref())

最佳答案

一如既往,MDN's docs help .

A WeakRef object contains a weak reference to an object, which is called its target or referent. A weak reference to an object is a reference that does not prevent the object from being reclaimed by the garbage collector. In contrast, a normal (or strong) reference keeps an object in memory. When an object no longer has any strong references to it, the JavaScript engine's garbage collector may destroy the object and reclaim its memory. If that happens, you can't get the object from a weak reference anymore.


在 JS 的几乎所有其他部分中,如果某个对象 (A) 持有对另一个对象 (B) 的引用,则 B 不会被垃圾回收,直到 A 也可以被完全垃圾回收。例如:
// top level
const theA = {};
(() => {
  // private scope
  const theB = { foo: 'foo' };
  theA.obj = obj;
})();
在这种情况下,theB永远不会被垃圾回收(除非 theA.obj 被重新分配),因为 theA在顶层包含一个持有对 theB 的引用的属性。 ;这是一个 强引用 ,这可以防止垃圾收集。
另一方面,WeakRef 提供了一个可以访问对象的包装器,同时不会阻止对该对象进行垃圾回收。调用deref()如果对象尚未被垃圾收集,则 WeakRef 上的对象将返回给您。如果已被 GC,.deref()将返回 undefined .

FinalizationRegistry处理类似的问题:

A FinalizationRegistry object lets you request a callback when an object is garbage-collected.


您首先使用要运行的回调定义注册表,然后调用 .register在您要观察的对象的注册表上。这将让您确切地知道何时收集垃圾。例如,以下将记录 Just got GCd!一旦obj被回收:
console.log('script starting...');

const r = new FinalizationRegistry(() => {
  console.log('Just got GCd!');
});
(() => {
  // private closure
  const obj = {};
  r.register(obj);
})();
您也可以在调用 .register 时传递一个值当对象被收集时,它被传递给回调。
new FinalizationRegistry((val) => {
  console.log(val);
});
r.register(obj, 'the object named "obj"')
将记录the object named "obj"它被GC'd。
说了这么多,有很少需要这些工具。正如 MDN 所说:

Correct use of FinalizationRegistry takes careful thought, and it's best avoided if possible. It's also important to avoid relying on any specific behaviors not guaranteed by the specification. When, how, and whether garbage collection occurs is down to the implementation of any given JavaScript engine. Any behavior you observe in one engine may be different in another engine, in another version of the same engine, or even in a slightly different situation with the same version of the same engine. Garbage collection is a hard problem that JavaScript engine implementers are constantly refining and improving their solutions to.


最好尽可能让引擎本身自动处理垃圾收集,除非您有充分的理由自己关心它。

关于javascript - 什么是 ES2021 (ES12) 中的 WeakRef 和终结器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66723378/

相关文章:

javascript - 在箭头函数上运行 eslint 时报告意外 token "="

javascript - 读取外部类的阴影私有(private)字段

javascript - Flow 不支持某些 JavaScript (ECMAScript) 内置方法,我该怎么办?

javascript - 使用 typescript 安装express.js 的正确方法是什么?

javascript - 如何在特定像素处停止图像?

javascript - 函数包含在javascript中

javascript - 当我点击打印按钮时隐藏 <td>

javascript - 日期处理 Unix 日期不正确(或者我错误地使用日期?)