Start · Sprachen · JavaScript · Referenz · new WeakRef()

new WeakRef()

Methode

Der Konstruktor <code>WeakRef()</code> erzeugt eine schwache Referenz auf ein Objekt, die dessen Freigabe durch den Garbage Collector nicht verhindert.

seit JavaScript ES2021 Kategorie: method-property

Signatur

new WeakRef(target)

Beschreibung

Mit new WeakRef(target) legst du ein WeakRef-Objekt an, das eine schwache Referenz auf target hält. Bei einer normalen (starken) Referenz bleibt ein Objekt so lange im Speicher, wie irgendwo darauf verwiesen wird. Eine schwache Referenz hält das Objekt dagegen nicht fest: Gibt es keine starken Referenzen mehr, darf der Garbage Collector es jederzeit freigeben.

Auf das Zielobjekt greifst du über WeakRef.prototype.deref() zu. Die Methode liefert das Objekt zurück, solange es noch existiert, und danach undefined. Typische Einsatzgebiete sind Caches für große, jederzeit neu erzeugbare Objekte (z. B. dekodierte Bilder, geparste Daten) und das Beobachten von DOM-Elementen, ohne sie künstlich am Leben zu halten.

WeakRef muss mit new aufgerufen werden. Als Ziel sind nur Objekte und nicht registrierte Symbole erlaubt, keine primitiven Werte. Häufig wird WeakRef zusammen mit FinalizationRegistry eingesetzt, damit man nach der Freigabe aufräumen kann (etwa verwaiste Einträge aus einer Map entfernen).

Parameter

Name Typ Default Beschreibung
$target Pflicht object | symbol Das Objekt, auf das schwach verwiesen werden soll. Seit ES2023 sind auch nicht registrierte Symbole erlaubt (also keine per Symbol.for() erzeugten). Primitive Werte lösen einen TypeError aus.

Rückgabewert

Typ
WeakRef
Beschreibung
Ein neues WeakRef-Objekt, das schwach auf target verweist.

Beispiele

WeakRef erzeugen und mit deref() auslesen

let user = { name: 'Anna', rolle: 'admin' };
const ref = new WeakRef(user);

// Solange eine starke Referenz besteht, ist das Objekt erreichbar
console.log(ref.deref()?.name);

// Starke Referenz aufheben – ab jetzt darf der GC das Objekt freigeben
user = null;
// Irgendwann später (nicht vorhersagbar):
// ref.deref() === undefined
Anna

Cache für aufwendig berechnete Objekte

const cache = new Map();
const registry = new FinalizationRegistry((key) => {
  // Eintrag nur löschen, wenn er nicht inzwischen ersetzt wurde
  const ref = cache.get(key);
  if (ref && !ref.deref()) cache.delete(key);
});

const ladeDaten = (key) => {
  const vorhanden = cache.get(key)?.deref();
  if (vorhanden) return vorhanden;

  const daten = { key, werte: new Array(100_000).fill(key.length) };
  cache.set(key, new WeakRef(daten));
  registry.register(daten, key);
  return daten;
};

const a = ladeDaten('bericht-2024');
const b = ladeDaten('bericht-2024');
console.log(a === b);
true

DOM-Element beobachten, ohne es festzuhalten

const el = document.createElement('div');
document.body.append(el);
const elRef = new WeakRef(el);

const timer = setInterval(() => {
  const node = elRef.deref();
  if (!node || !node.isConnected) {
    console.log('Element entfernt – Timer wird beendet');
    clearInterval(timer);
    return;
  }
  node.textContent = new Date().toLocaleTimeString('de-DE');
}, 1000);

// Später: el.remove();

Ungültige Ziele lösen TypeError aus

try {
  new WeakRef(42);
} catch (err) {
  console.log(err instanceof TypeError);
}

try {
  WeakRef({}); // ohne new
} catch (err) {
  console.log(err.constructor.name);
}
true TypeError

// Wichtig · Fallstricke

  • Nicht deterministisch: Wann (und ob überhaupt) der Garbage Collector ein Objekt freigibt, hängt von der Engine ab. Programmlogik darf nie davon abhängen, dass deref() zu einem bestimmten Zeitpunkt undefined liefert.
  • Innerhalb desselben synchronen Durchlaufs (Job) bleibt ein per deref() erhaltenes oder mit new WeakRef() frisch referenziertes Ziel garantiert erhalten. Ergebnis von deref() deshalb in einer lokalen Variable speichern, statt mehrfach aufzurufen.
  • Primitive Werte und registrierte Symbole (Symbol.for()) als target führen zu einem TypeError, ebenso ein Aufruf ohne new.
  • Nutze WeakRef sparsam: Für reine Zuordnungen von Metadaten zu Objekten sind WeakMap bzw. WeakSet meist die bessere, einfachere Wahl.
  • Kompatibilität: Chrome/Edge 84+, Firefox 79+, Safari 14.1+, Node.js 14.6+. Symbole als Ziel erst ab ES2023 (neuere Engines).