Signatur
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
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);
Unterklasse erbt den Getter (liefert this)
class TagSet extends Set {}
console.log(TagSet[Symbol.species] === TagSet);
console.log(TagSet[Symbol.species] === Set);
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);
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));
// Wichtig · Fallstricke
- Ohne Wirkung auf eingebaute Methoden: Anders als bei
Array,PromiseoderArrayBufferliest keineSet-MethodeSymbol.speciesaus. Wenn du den Getter überschreibst, ändert das nichts anunion(),intersection()und den anderen Mengen-Methoden. Diese geben immer ein neues, normalesSetzurü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] = Xwird im nicht-strikten Modus stillschweigend ignoriert und löst im Strict Mode einenTypeErroraus. Umdefinieren geht nur überObject.defineProperty(die Eigenschaft istconfigurable) oder überstatic getin 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+).