Signatur
Beschreibung
unregister() ist das Gegenstück zu register(). Wenn Sie ein Objekt mit registry.register(target, heldValue, unregisterToken) anmelden, können Sie diese Registrierung später über das Token wieder entfernen. Danach ruft die Registry den Aufräum-Callback für dieses Ziel nicht mehr auf, auch wenn der Garbage Collector das Objekt später freigibt.
Typischerweise nutzt man das bei expliziter Ressourcenfreigabe: Eine Klasse hält z. B. einen externen Handle wie einen Datei-Deskriptor, einen WebAssembly-Speicherblock oder eine Worker-Verbindung. Die Registry dient nur als Sicherheitsnetz für den Fall, dass der Nutzer close() vergisst. Ruft er close() ordnungsgemäß auf, wird die Ressource sofort freigegeben und die Registrierung mit unregister() entfernt. So wird die Ressource nicht zweimal freigegeben.
Das Token muss ein Objekt oder ein nicht registriertes Symbol sein. Oft nimmt man das Zielobjekt selbst als Token. Das ist unproblematisch, denn die Registry hält Tokens nur schwach. Ein Token kann für mehrere Registrierungen verwendet werden. unregister() entfernt dann alle auf einmal.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $unregisterToken Pflicht | object | symbol | Das Token, das beim Aufruf von register() als dritter Parameter übergeben wurde. Es muss ein Objekt oder ein nicht registriertes Symbol sein, also nicht über Symbol.for() erzeugt. Sonst wird ein TypeError geworfen. |
Beispiele
Grundlegendes Registrieren und Abmelden
const registry = new FinalizationRegistry((heldValue) => {
console.log(`Aufgeräumt: ${heldValue}`);
});
const obj = { name: 'Cache-Eintrag' };
// Objekt selbst dient als Abmelde-Token
registry.register(obj, 'cache-42', obj);
console.log(registry.unregister(obj)); // Registrierung entfernt
console.log(registry.unregister(obj)); // nichts mehr vorhanden
Sicherheitsnetz für explizit freigegebene Ressourcen
const handles = new Set();
const openHandle = (id) => { handles.add(id); return id; };
const closeHandle = (id) => { handles.delete(id); console.log(`Handle ${id} geschlossen`); };
const registry = new FinalizationRegistry((id) => {
console.warn(`Handle ${id} wurde nicht geschlossen – hole das nach`);
closeHandle(id);
});
class Resource {
#id;
constructor(id) {
this.#id = openHandle(id);
// this als Ziel UND als Token
registry.register(this, this.#id, this);
}
close() {
if (this.#id === null) return;
closeHandle(this.#id);
registry.unregister(this); // Callback soll nicht mehr laufen
this.#id = null;
}
}
const res = new Resource(7);
res.close();
console.log(handles.size);
Ein Token für mehrere Registrierungen
const registry = new FinalizationRegistry((v) => console.log('Freigegeben:', v));
const session = {}; // gemeinsames Token
const a = {};
const b = {};
registry.register(a, 'Objekt A', session);
registry.register(b, 'Objekt B', session);
// Entfernt beide Registrierungen gleichzeitig
console.log(registry.unregister(session));
// Ungültiges Token führt zu einem Fehler
try {
registry.unregister('kein-objekt');
} catch (err) {
console.log(err.constructor.name);
}
// Wichtig · Fallstricke
- Ohne Token kein Abmelden: Wurde bei
register()kein drittes Argument übergeben, lässt sich die Registrierung nicht mehr entfernen. - Ungültige Tokens: Primitive Werte wie Strings, Zahlen oder
undefinedsowie überSymbol.for()registrierte Symbole lösen einenTypeErroraus. Nicht registrierte Symbole als Token werden erst seit ES2023 unterstützt, in älteren Engines nur Objekte. - Kein Zeitpunkt garantiert: Wann oder ob ein Aufräum-Callback überhaupt läuft, ist nicht festgelegt. Verlassen Sie sich deshalb nie auf die Registry für kritische Logik. Geben Sie Ressourcen explizit frei und nutzen Sie
unregister(), um das Sicherheitsnetz abzuschalten. - Rückgabewert
falsebedeutet nicht unbedingt einen Fehler. Der Callback kann bereits gelaufen sein, oder das Ziel wurde schon eingesammelt und steht zur Bereinigung an. - Token schwach gehalten: Die Registry hält das Token nicht stark. Das Zielobjekt als eigenes Token zu verwenden, verhindert die Speicherbereinigung also nicht. Der gehaltene Wert (
heldValue) darf dagegen nicht das Ziel sein. - Kompatibilität: Wird von allen modernen Browsern unterstützt (Chrome 84+, Firefox 79+, Safari 14.1+), außerdem ab Node.js 14.6. Im Internet Explorer gibt es die Methode nicht, und ein Polyfill ist nicht möglich.