Signatur
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
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');
}
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);
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 Zeitpunktundefinedliefert – auch nicht in Tests. - Ergebnis zwischenspeichern: Nicht
ref.deref().foound später erneutref.deref().barschreiben, besonders nicht über einawaithinweg. Einmal abrufen, in einer Variablen halten, aufundefinedprü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
WeakRefaus. - Wird
deref()mit einemthisaufgerufen, das keinWeakRefist, wird einTypeErrorgeworfen. - Das TC39-Proposal rät,
WeakRefnur sparsam einzusetzen; oft sindWeakMap/WeakSetdie bessere Wahl. - Kompatibilität: Chrome/Edge 84+, Firefox 79+, Safari 14.1+, Node.js 14.6+. Symbole als Ziel sind erst ab ES2023 erlaubt.