Start · Sprachen · JavaScript · Referenz · Set[Symbol.species]

Set[Symbol.species]

Eigenschaft

Statischer Getter, der den Konstruktor zurückgibt, mit dem abgeleitete <code>Set</code>-Objekte erzeugt werden sollen. Die eingebauten <code>Set</code>-Methoden verwenden ihn derzeit nicht.

seit JavaScript ES2015 (Baseline: alle Browser, Node.js 6.5+) Kategorie: method-property

Signatur

static get Set[Symbol.species]

Beschreibung

Set[Symbol.species] ist eine statische Zugriffseigenschaft (nur Getter) des Set-Konstruktors. Der Getter liefert einfach this zurück. Bei Set selbst ist das also Set, bei einer Unterklasse wie class MySet extends Set {} ist es MySet.

Das Symbol Symbol.species gibt es, damit eingebaute Methoden neue Objekte vom „richtigen“ Typ erzeugen können. Bei Array nutzen zum Beispiel map(), filter() und slice() den Species-Konstruktor. Bei Set ist die Eigenschaft dagegen ungenutzt: Keine eingebaute Set-Methode liest sie aus. Auch die neueren Mengen-Methoden wie union(), intersection(), difference() und symmetricDifference() geben immer ein normales Set zurück, auch wenn sie auf einer Unterklasse aufgerufen werden.

Praktisch brauchst du die Eigenschaft vor allem in zwei Fällen: Du schreibst eigenen Code, der dem Species-Muster folgt (etwa eine generische Kopierfunktion), oder du willst das Verhalten der Sprache besser verstehen. Wenn du von Set ableitest und Methoden Instanzen deiner Unterklasse zurückgeben sollen, musst du diese Methoden selbst überschreiben.

Rückgabewert

Typ
Function
Beschreibung
Den Wert von this, also den Konstruktor, auf dem der Getter aufgerufen wurde: Set oder die jeweilige Unterklasse.

Beispiele

Grundverhalten und Eigenschafts-Deskriptor

console.log(Set[Symbol.species] === Set);

const desc = Object.getOwnPropertyDescriptor(Set, Symbol.species);
console.log(typeof desc.get, desc.set, desc.enumerable, desc.configurable);
console.log(desc.get.name);
true function undefined false true get [Symbol.species]

Unterklasse erbt den Getter (liefert this)

class TagSet extends Set {}

console.log(TagSet[Symbol.species] === TagSet);
console.log(TagSet[Symbol.species] === Set);
true false

Eingebaute Methoden ignorieren Species

class TagSet extends Set {
  // Überschreiben hat keine Wirkung auf eingebaute Set-Methoden
  static get [Symbol.species]() {
    return TagSet;
  }
}

const a = new TagSet(['js', 'css']);
const b = new Set(['html']);

// union() gibt immer ein normales Set zurück (ES2025)
const u = a.union(b);
console.log(u instanceof TagSet, u instanceof Set);
false true

Eigene Kopierfunktion nach dem Species-Muster

// Generische Kopie, die Symbol.species respektiert
const cloneSet = (set) => {
  const Ctor = set.constructor?.[Symbol.species] ?? Set;
  return new Ctor(set);
};

class TagSet extends Set {
  toString() {
    return [...this].join(', ');
  }
}

const tags = new TagSet(['js', 'node']);
const copy = cloneSet(tags);
console.log(copy instanceof TagSet, String(copy));
true js, node

// Wichtig · Fallstricke

  • Ohne Wirkung auf eingebaute Methoden: Anders als bei Array, Promise oder ArrayBuffer liest keine Set-Methode Symbol.species aus. Wenn du den Getter überschreibst, ändert das nichts an union(), intersection() und den anderen Mengen-Methoden. Diese geben immer ein neues, normales Set zurück.
  • Eigene Methoden: Sollen Mengen-Operationen Instanzen deiner Unterklasse liefern, musst du die Methoden überschreiben, zum Beispiel union(other) { return new TagSet(super.union(other)); }.
  • Nur Getter: Die Eigenschaft hat keinen Setter. Eine Zuweisung wie Set[Symbol.species] = X wird im nicht-strikten Modus stillschweigend ignoriert und löst im Strict Mode einen TypeError aus. Umdefinieren geht nur über Object.defineProperty (die Eigenschaft ist configurable) oder über static get in einer Unterklasse.
  • Kompatibilität: Der Getter selbst wird seit ES2015 von allen modernen Browsern und von Node.js unterstützt. Die Mengen-Methoden wie union() sind erst seit 2024 Baseline (ES2025, Node.js 22+).