Signatur
Beschreibung
Die Methode has() prüft, ob ein bestimmter Wert in einem WeakSet enthalten ist. Verglichen wird über die Identität (Referenzgleichheit): Zwei Objekte mit gleichem Inhalt gelten als verschieden, wenn es sich nicht um dieselbe Referenz handelt.
Ein WeakSet hält seine Einträge nur schwach. Gibt es außerhalb des Sets keine weiteren Referenzen auf ein Objekt, kann die Garbage Collection es entfernen. Deshalb eignet sich has() gut, um Objekte zu „markieren“, ohne ihre Lebensdauer zu verlängern, zum Beispiel für bereits verarbeitete DOM-Knoten, besuchte Knoten beim Durchlaufen zyklischer Strukturen oder Instanzen, die über einen privaten Konstruktor erzeugt wurden (Brand-Check).
Wenn der übergebene Wert kein Objekt ist (z. B. ein String, eine Zahl, null oder ein mit Symbol.for() registriertes Symbol), gibt has() einfach false zurück und wirft keinen Fehler, anders als add().
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $value Pflicht | any | Der Wert, nach dem gesucht wird. Nur Objekte und nicht registrierte Symbole können überhaupt enthalten sein. Für alle anderen Werte ist das Ergebnis immer false. |
Rückgabewert
true, wenn genau diese Referenz im WeakSet enthalten ist, sonst false.Beispiele
Grundlegende Prüfung und Referenzgleichheit
const ws = new WeakSet();
const user = { name: 'Anna' };
ws.add(user);
console.log(ws.has(user)); // gleiche Referenz
console.log(ws.has({ name: 'Anna' })); // anderes Objekt, gleicher Inhalt
console.log(ws.has('Anna')); // Primitive: kein Fehler, nur false
DOM-Elemente nur einmal initialisieren
const initialized = new WeakSet();
const initWidget = (el) => {
if (initialized.has(el)) return; // bereits eingerichtet
el.addEventListener('click', () => console.log('Klick auf', el.id));
initialized.add(el);
};
document.querySelectorAll('.widget').forEach(initWidget);
// Ein erneuter Aufruf hängt keine doppelten Listener an
document.querySelectorAll('.widget').forEach(initWidget);
Zyklische Strukturen sicher durchlaufen
const countNodes = (node, seen = new WeakSet()) => {
if (node === null || typeof node !== 'object' || seen.has(node)) return 0;
seen.add(node);
return 1 + Object.values(node).reduce((sum, v) => sum + countNodes(v, seen), 0);
};
const a = { name: 'a' };
const b = { name: 'b', ref: a };
a.ref = b; // Zyklus
console.log(countNodes(a));
Brand-Check für echte Instanzen
const instances = new WeakSet();
class Token {
constructor() { instances.add(this); }
static isToken(obj) { return instances.has(obj); }
}
const t = new Token();
const fake = Object.create(Token.prototype);
console.log(Token.isToken(t));
console.log(Token.isToken(fake));
console.log(fake instanceof Token); // instanceof lässt sich täuschen
// Wichtig · Fallstricke
- Kein Fehler bei Primitiven:
has(42)oderhas(null)liefertfalse, währendadd()hier einenTypeErrorwirft. - Nur Referenzgleichheit: Strukturell gleiche Objekte werden nicht erkannt. Man braucht die ursprüngliche Referenz.
- Nicht aufzählbar: Ein
WeakSethat keinsize, keinforEach()und ist nicht iterierbar.has()ist die einzige Möglichkeit, den Inhalt abzufragen. - Symbole: Nicht registrierte Symbole als Werte werden erst seit ES2023 unterstützt (Chrome 108+, Firefox 138+, Safari 17.4+). Bei registrierten Symbolen (
Symbol.for()) lieferthas()immerfalse. - Wird
has()auf einem Objekt aufgerufen, das keinWeakSetist (z. B. überWeakSet.prototype.has.call({}, obj)), wirft es einenTypeError. - Die Methode selbst wird ab ES2015 in allen modernen Browsern und in Node.js unterstützt.