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

WeakSet.prototype.add()

Methode

Fügt ein Objekt oder ein nicht registriertes Symbol zu einem <code>WeakSet</code> hinzu, falls es dort noch nicht enthalten ist, und gibt das <code>WeakSet</code> selbst zurück.

seit JavaScript ES2015 (Symbole als Werte: ES2023) Kategorie: method-property

Signatur

WeakSet.prototype.add(value)

Beschreibung

add() nimmt einen Wert in ein WeakSet auf. Ist der Wert schon enthalten, passiert nichts. Weil WeakSet seine Einträge nur schwach referenziert, hält add() das Objekt nicht künstlich am Leben: Gibt es sonst keine Referenz mehr darauf, darf die Speicherbereinigung (Garbage Collector) es entfernen, und es verschwindet dann auch aus dem WeakSet.

Typische Einsätze sind das Markieren von Objekten, ohne sie selbst zu verändern. Beispiele: bereits besuchte Knoten beim Durchlaufen zyklischer Strukturen, schon initialisierte DOM-Elemente oder „geprüfte“ Instanzen, etwa beim Nachbilden privater Klassenmarken (sogenannte Brand-Checks).

Erlaubt sind nur Werte, die per Speicherbereinigung entfernt werden können: Objekte (auch Funktionen und Arrays) und seit ES2023 nicht registrierte Symbole. Primitive Werte wie Zahlen, Strings oder mit Symbol.for() registrierte Symbole lösen einen TypeError aus.

Weil die Methode das WeakSet selbst zurückgibt, lassen sich mehrere Aufrufe aneinanderhängen: ws.add(a).add(b).

Parameter

Name Typ Default Beschreibung
$value Pflicht object | symbol Der Wert, der hinzugefügt werden soll. Er muss ein Objekt oder ein nicht registriertes Symbol sein. Andere Werte führen zu einem TypeError.

Rückgabewert

Typ
WeakSet
Beschreibung
Dasselbe WeakSet-Objekt, auf dem add() aufgerufen wurde. Dadurch lassen sich Aufrufe verketten.

Beispiele

Grundlegende Nutzung und Verkettung

const gesehen = new WeakSet();
const userA = { name: 'Anna' };
const userB = { name: 'Ben' };

gesehen.add(userA).add(userB);
gesehen.add(userA); // schon enthalten – keine Wirkung

console.log(gesehen.has(userA));
console.log(gesehen.has({ name: 'Anna' })); // anderes Objekt!
true false

Zyklische Strukturen sicher durchlaufen

const zaehleKnoten = (knoten, besucht = new WeakSet()) => {
  if (knoten === null || typeof knoten !== 'object' || besucht.has(knoten)) return 0;
  besucht.add(knoten);
  return 1 + Object.values(knoten).reduce((sum, v) => sum + zaehleKnoten(v, besucht), 0);
};

const a = { id: 1 };
const b = { id: 2, parent: a };
a.child = b; // Zyklus a -> b -> a

console.log(zaehleKnoten(a));
2

DOM-Elemente nur einmal initialisieren

const initialisiert = new WeakSet();

const initTooltip = (el) => {
  if (initialisiert.has(el)) return;
  el.addEventListener('mouseenter', () => console.log(el.dataset.tip));
  initialisiert.add(el);
};

document.querySelectorAll('[data-tip]').forEach(initTooltip);
// Später erneut aufrufen ist gefahrlos – keine doppelten Listener
document.querySelectorAll('[data-tip]').forEach(initTooltip);

Ungültige Werte lösen TypeError aus

const ws = new WeakSet();

for (const wert of [42, 'text', Symbol.for('reg'), Symbol('lokal')]) {
  try {
    ws.add(wert);
    console.log('OK:', String(wert));
  } catch (e) {
    console.log(e.constructor.name + ':', String(wert));
  }
}
TypeError: 42 TypeError: text TypeError: Symbol(reg) OK: Symbol(lokal)

// Wichtig · Fallstricke

  • Nur Objekte und nicht registrierte Symbole: Primitive Werte und Symbole aus Symbol.for() lösen einen TypeError aus. Symbole als Werte gibt es erst seit ES2023 (Chrome 108+, Firefox 139+, Safari 16.4+, Node.js 20+). Ältere Umgebungen lehnen jedes Symbol ab.
  • Vergleich über die Identität: Zwei Objekte mit gleichem Inhalt sind unterschiedliche Einträge. Es zählt nur die Referenz.
  • Keine Aufzählung: Ein WeakSet hat kein size, keine Iteration und kein clear(). Was per add() aufgenommen wurde, lässt sich nur mit has() prüfen oder mit delete() entfernen. Wer alle Einträge auflisten muss, braucht ein Set.
  • Speicherbereinigung ist nicht beobachtbar: Wann ein Eintrag verschwindet, ist nicht festgelegt. Programmlogik darf sich nicht darauf verlassen.
  • Der Aufruf auf einem Objekt, das kein WeakSet ist, zum Beispiel WeakSet.prototype.add.call({}, obj), löst einen TypeError aus.
  • Die Methode selbst (ohne Symbole) wird seit ES2015 in allen modernen Browsern und in Node.js unterstützt.