Start · Sprachen · JavaScript · Referenz · WeakSet.prototype.has()

WeakSet.prototype.has()

Methode

Prüft, ob ein Objekt (oder nicht registriertes Symbol) im <code>WeakSet</code> enthalten ist, und gibt <code>true</code> oder <code>false</code> zurück.

seit JavaScript ES2015 (Baseline: alle Browser) Kategorie: method-property

Signatur

WeakSet.prototype.has(value)

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

Typ
boolean
Beschreibung
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
true false 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));
2

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

// Wichtig · Fallstricke

  • Kein Fehler bei Primitiven: has(42) oder has(null) liefert false, während add() hier einen TypeError wirft.
  • Nur Referenzgleichheit: Strukturell gleiche Objekte werden nicht erkannt. Man braucht die ursprüngliche Referenz.
  • Nicht aufzählbar: Ein WeakSet hat kein size, kein forEach() 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()) liefert has() immer false.
  • Wird has() auf einem Objekt aufgerufen, das kein WeakSet ist (z. B. über WeakSet.prototype.has.call({}, obj)), wirft es einen TypeError.
  • Die Methode selbst wird ab ES2015 in allen modernen Browsern und in Node.js unterstützt.