Start · Sprachen · JavaScript · Referenz · WeakRef.prototype.deref()

WeakRef.prototype.deref()

Methode

Gibt das Zielobjekt eines <code>WeakRef</code> zurück oder <code>undefined</code>, wenn die Garbage Collection es bereits entfernt hat.

seit JavaScript ES2021 Kategorie: method-property

Signatur

WeakRef.prototype.deref()

Beschreibung

Die Methode deref() liefert das Objekt (oder nicht registrierte Symbol), auf das ein WeakRef schwach verweist. Solange das Ziel noch im Speicher ist, bekommst du eine ganz normale, starke Referenz darauf zurück. Hat die Garbage Collection das Ziel inzwischen entfernt, gibt deref() undefined zurück.

Typische Einsatzgebiete sind Caches für große, jederzeit neu erzeugbare Objekte (z. B. dekodierte Bilder, geparste Dokumente), Beobachter-Muster, bei denen ein Listener nicht für das Überleben des Beobachters sorgen soll, und Zuordnungen zu DOM-Elementen, die jederzeit aus dem Dokument entfernt werden können.

Wichtig ist die Semantik innerhalb eines synchronen Durchlaufs: Hat deref() einmal ein Objekt geliefert, räumt die Engine es bis zum Ende des aktuellen Jobs (also bis zur nächsten Microtask-Grenze) nicht weg. Mehrere deref()-Aufrufe im selben synchronen Codeblock liefern daher dasselbe Ergebnis. Nach einem await oder in einem späteren Callback kann das Ziel aber verschwunden sein – deshalb das Ergebnis immer in einer lokalen Variablen speichern und auf undefined prüfen.

Rückgabewert

Typ
object | symbol | undefined
Beschreibung
Das Zielobjekt bzw. Symbol des WeakRef oder undefined, wenn es von der Garbage Collection entfernt wurde.

Beispiele

Grundlegende Nutzung mit Prüfung auf undefined

let config = { theme: 'dark', lang: 'de' };
const ref = new WeakRef(config);

const target = ref.deref();
if (target) {
  console.log(target.theme);
} else {
  console.log('Objekt wurde bereits eingesammelt');
}
dark

Cache für teure Berechnungen

const cache = new Map();

const computeReport = (id) => ({ id, rows: new Array(100_000).fill(id) });

const getReport = (id) => {
  const cached = cache.get(id)?.deref();
  if (cached) {
    console.log(`Cache-Treffer für ${id}`);
    return cached;
  }
  const report = computeReport(id);
  cache.set(id, new WeakRef(report));
  console.log(`Neu berechnet: ${id}`);
  return report;
};

const a = getReport('q1');
const b = getReport('q1'); // a hält den Bericht noch stark fest
console.log(a === b);
Neu berechnet: q1 Cache-Treffer für q1 true

Periodischer Zähler, der ein DOM-Element nicht am Leben hält

const startCounter = (element) => {
  const ref = new WeakRef(element);
  let count = 0;

  const timer = setInterval(() => {
    const el = ref.deref(); // Ergebnis einmal lokal speichern
    if (!el) {
      console.log('Element weg – Timer wird beendet');
      clearInterval(timer);
      return;
    }
    el.textContent = `Sekunden: ${++count}`;
  }, 1000);
};

const div = document.createElement('div');
document.body.append(div);
startCounter(div);
// Später: div.remove(); – sobald keine starke Referenz mehr existiert,
// kann der GC das Element einsammeln und der Timer stoppt sich selbst.

// Wichtig · Fallstricke

  • Nicht deterministisch: Wann (und ob überhaupt) ein Objekt eingesammelt wird, hängt vollständig von der Engine ab. Programmlogik darf nie davon abhängen, dass deref() zu einem bestimmten Zeitpunkt undefined liefert – auch nicht in Tests.
  • Ergebnis zwischenspeichern: Nicht ref.deref().foo und später erneut ref.deref().bar schreiben, besonders nicht über ein await hinweg. Einmal abrufen, in einer Variablen halten, auf undefined prüfen.
  • Starke Referenz: Der Rückgabewert ist eine normale Referenz. Wer ihn dauerhaft speichert (z. B. in einer Closure oder einem Array), verhindert die Garbage Collection und hebelt den Zweck von WeakRef aus.
  • Wird deref() mit einem this aufgerufen, das kein WeakRef ist, wird ein TypeError geworfen.
  • Das TC39-Proposal rät, WeakRef nur sparsam einzusetzen; oft sind WeakMap/WeakSet die bessere Wahl.
  • Kompatibilität: Chrome/Edge 84+, Firefox 79+, Safari 14.1+, Node.js 14.6+. Symbole als Ziel sind erst ab ES2023 erlaubt.