Start · Sprachen · JavaScript · Referenz · FinalizationRegistry.prototype.unregister()

FinalizationRegistry.prototype.unregister()

Methode

Entfernt alle Registrierungen aus einer <code>FinalizationRegistry</code>, die mit dem angegebenen Abmelde-Token angelegt wurden. Deren Aufräum-Callbacks werden danach nicht mehr aufgerufen.

seit JavaScript ES2021 Kategorie: method-property

Signatur

FinalizationRegistry.prototype.unregister(unregisterToken)

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
true false

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);
Handle 7 geschlossen 0

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);
}
true TypeError

// 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 undefined sowie über Symbol.for() registrierte Symbole lösen einen TypeError aus. 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 false bedeutet 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.