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

2023-11-23

我想了解什么是WeakRef和终结器ES2021 with a 真正的简单例子 and Where使用它们。

I know, WeakRef是一个类。这将允许开发人员创建对对象的弱引用,而终结器或FinalizationRegistry允许您注册当对象被垃圾收集时将调用的回调函数

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

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

一如既往,MDN 的文档帮助.

WeakRef 对象包含对对象的弱引用,称为其目标或引用对象。对对象的弱引用是不会阻止垃圾收集器回收该对象的引用。相反,普通(或强)引用将对象保留在内存中。当一个对象不再有任何强引用时,JavaScript 引擎的垃圾收集器可能会销毁该对象并回收其内存。如果发生这种情况,您将无法再从弱引用获取对象。

在 JS 的几乎所有其他部分中,如果某个对象 (A) 持有对另一个对象 (B) 的引用,则在 A 也可以完全垃圾收集之前,B 不会被垃圾收集。例如:

// top level
const theA = {};
(() => {
  // private scope
  const theB = { foo: 'foo' };
  theA.obj = obj;
})();

在这种情况下,theB will never被垃圾收集(除非theA.obj被重新分配)因为theA顶层包含一个属性,该属性保存对theB;它是强参考,这会阻止垃圾收集。

另一方面,WeakRef 提供了一个可以访问对象的包装器,同时不阻止该对象的垃圾收集。呼唤deref()在 WeakRef 上将返回该对象如果它还没有被垃圾收集。如果它已经被 GC 了,.deref()将返回undefined.


最终确定注册表处理类似的问题:

FinalizationRegistry 对象允许您在对象被垃圾收集时请求回调。

您首先使用要运行的回调定义注册表,然后调用.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 了。

综上所述,有rarely需要这些工具。正如 MDN 所说:

正确使用 FinalizationRegistry 需要仔细考虑,如果可能的话最好避免使用。避免依赖规范未保证的任何特定行为也很重要。何时、如何以及是否发生垃圾收集取决于任何给定 JavaScript 引擎的实现。您在一个引擎中观察到的任何行为在另一个引擎、同一引擎的另一个版本中甚至在同一引擎的同一版本的情况下可能会有所不同。垃圾收集是 JavaScript 引擎实现者不断完善和改进其解决方案的一个难题。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ES2021 (ES12) 中的 WeakRef 和终结器是什么 的相关文章

随机推荐