Abo*_*zlR 6 javascript ecmascript-2021
我想通过一个简单的例子来了解ES2021WeakRef中的什么是终结器以及在哪里使用它们。
我知道,WeakRef是一个班级。这将允许开发人员创建对对象的弱引用,而终结器或FinalizationRegistry允许您注册将在对象被垃圾收集时调用的回调函数
const myWeakRef = new WeakRef({
name: 'Cache',
size: 'unlimited'
})
// Log the value of "myWeakRef":
console.log(myWeakRef.deref())
Run Code Online (Sandbox Code Playgroud)
一如既往,MDN 的文档会提供帮助。
WeakRef 对象包含对对象的弱引用,称为其目标或引用对象。对对象的弱引用是不会阻止垃圾收集器回收该对象的引用。相反,普通(或强)引用将对象保留在内存中。当一个对象不再有任何强引用时,JavaScript 引擎的垃圾收集器可能会销毁该对象并回收其内存。如果发生这种情况,您将无法再从弱引用获取对象。
在 JS 的几乎所有其他部分中,如果某个对象 (A) 持有对另一个对象 (B) 的引用,则在 A 也可以完全垃圾收集之前,B 不会被垃圾收集。例如:
// top level
const theA = {};
(() => {
// private scope
const theB = { foo: 'foo' };
theA.obj = obj;
})();
Run Code Online (Sandbox Code Playgroud)
在这种情况下,永远theB不会被垃圾回收(除非被重新分配),因为在顶层包含一个保存对;的引用的属性。它是一个强引用,可以防止垃圾收集。theA.objtheAtheB
另一方面,WeakRef 提供了一个可以访问对象的包装器,同时不阻止该对象的垃圾收集。如果对象尚未被垃圾回收,则调用deref()WeakRef 将返回该对象。如果已被 GC 回收,将返回。.deref()undefined
FinalizationRegistry处理类似的问题:
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);
})();
Run Code Online (Sandbox Code Playgroud)
您还可以在调用时传递一个值,.register该值在收集对象时传递给回调。
new FinalizationRegistry((val) => {
console.log(val);
});
Run Code Online (Sandbox Code Playgroud)
r.register(obj, 'the object named "obj"')
Run Code Online (Sandbox Code Playgroud)
将记录the object named "obj"它被GC'd。
综上所述,很少需要这些工具。正如 MDN 所说:
正确使用 FinalizationRegistry 需要仔细考虑,如果可能的话最好避免使用。避免依赖规范未保证的任何特定行为也很重要。何时、如何以及是否发生垃圾收集取决于任何给定 JavaScript 引擎的实现。您在一个引擎中观察到的任何行为在另一个引擎、同一引擎的另一个版本中可能会有所不同,甚至在同一引擎的同一版本的情况下也可能略有不同。垃圾收集是 JavaScript 引擎实现者不断完善和改进其解决方案的一个难题。
最好尽可能让引擎本身自动处理垃圾收集,除非您有充分的理由自己关心它。
| 归档时间: |
|
| 查看次数: |
1613 次 |
| 最近记录: |