--- title: FinalizationRegistry slug: Web/JavaScript/Reference/Global_Objects/FinalizationRegistry tags: - FinalizationRegistry - GC - 垃圾回收 translation_of: Web/JavaScript/Reference/Global_Objects/FinalizationRegistry ---
{{JSRef}}

FinalizationRegistry 对象可以让你在对象被垃圾回收时请求一个回调。

描述

FinalizationRegistry 提供了这样的一种方法:当一个在注册表中注册的对象被回收时,请求在某个时间点上调用一个清理回调。(清理回调有时被称为 finalizer )。

备注: 清理回调不应被用于必要的程序逻辑。详情请看清理回调的注意事项

你在回调中创建了如下的 registry:

const registry = new FinalizationRegistry(heldValue => {
  // ....
});

然后,你可以通过调用`register`方法,注册任何你想要清理回调的对象,传入该对象和*所含的值*。

registry.register(theObject, "some value");

The registry does not keep a strong reference to the object, as that would defeat the purpose (if the registry held it strongly, the object would never be reclaimed).

If theObject is reclaimed, your cleanup callback may be called at some point with the held value you provided for it ("some value" in the above). The held value can be any value you like: a primitive or an object, even undefined. If the held value is an object, the registry keeps a strong reference to it (so it can pass it to your cleanup callback later).

If you might want to unregister an object later, you pass a third value, which is the unregistration token you'll use later when calling the registry's unregister function to unregister the object. The registry only keeps a weak reference to the unregister token.

It's common to use the object itself as the unregister token, which is just fine:

registry.register(theObject, "some value", theObject);
// ...some time later, if you don't care about `theObject` anymore...
registry.unregister(theObject);

It doesn't have to be the same object, though; it can be a different one:

registry.register(theObject, "some value", tokenObject);
// ...some time later, if you don't care about `theObject` anymore...
registry.unregister(tokenObject);

Constructor

{{jsxref("FinalizationRegistry/FinalizationRegistry", "FinalizationRegistry()")}}
Creates a new FinalizationRegistry object.

Instance methods

{{jsxref("FinalizationRegistry.register", "FinalizationRegistry.prototype.register()")}}
Registers an object with the registry in order to get a cleanup callback when/if the object is garbage-collected.
{{jsxref("FinalizationRegistry.unregister", "FinalizationRegistry.prototype.unregister()")}}
Unregisters an object from the registry.

Avoid where possible

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.

Here are some specific points that the authors of the WeakRef proposal that FinalizationRegistry is part of included in its explainer document:

Garbage collectors are complicated. If an application or library depends on GC cleaning up a FinalizationRegistry or calling a finalizer [cleanup callback] in a timely, predictable manner, it's likely to be disappointed: the cleanup may happen much later than expected, or not at all. Sources of variability include:

Notes on cleanup callbacks

Some notes on cleanup callbacks:

Examples

Creating a new registry

You create the registry passing in the callback:

const registry = new FinalizationRegistry(heldValue => {
  // ....
});

Registering objects for cleanup

Then you register any objects you want a cleanup callback for by calling the `register` method, passing in the object and a *held value* for it:

registry.register(theObject, "some value");

Specifications

Specification
{{SpecName('WeakRefs', '#sec-finalization-registry-objects', 'FinalizationRegistry')}}

Browser compatibility

{{Compat("javascript.builtins.FinalizationRegistry")}}

See also