Signatur
Beschreibung
Symbol() liefert bei jedem Aufruf einen neuen, einmaligen primitiven Wert. Auch zwei Symbole mit derselben Beschreibung sind nie gleich. Deshalb eignen sich Symbole gut als Eigenschaftsschlüssel, die nicht mit anderen Schlüsseln kollidieren. Das ist praktisch für Metadaten an fremden Objekten, für „private“ Eigenschaften nach Konvention oder für Protokolle wie Symbol.iterator.
Anders als String() oder Number() ist Symbol kein vollwertiger Konstruktor. Der Ausdruck new Symbol() wirft einen TypeError. So wird verhindert, dass versehentlich Wrapper-Objekte entstehen. Braucht man tatsächlich ein Wrapper-Objekt, bekommt man es mit Object(sym).
Das optionale Argument description dient nur der Fehlersuche. Es erscheint in toString() und in der Konsole und ist über sym.description lesbar. Auf die Identität des Symbols hat es keinen Einfluss. Wer ein Symbol über mehrere Module oder Realms (z. B. iframes) hinweg teilen will, verwendet stattdessen die globale Symbol-Registry mit Symbol.for(key).
Eigenschaften mit Symbol-Schlüsseln tauchen in for...in, Object.keys() und JSON.stringify() nicht auf. Man erreicht sie gezielt über Object.getOwnPropertySymbols() oder Reflect.ownKeys().
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $description | string | undefined | undefined | Optionale Beschreibung für die Fehlersuche. Werte, die keine Zeichenketten sind, werden in einen String umgewandelt. Auf die Einmaligkeit des Symbols hat sie keinen Einfluss. |
Rückgabewert
typeof ergibt "symbol").Beispiele
Symbole erzeugen – und warum new scheitert
const a = Symbol('id');
const b = Symbol('id');
console.log(typeof a); // Typ prüfen
console.log(a === b); // gleiche Beschreibung, trotzdem verschieden
console.log(a.description);
console.log(a.toString());
try {
new Symbol('id');
} catch (err) {
console.log(err.name);
}
Kollisionsfreie Metadaten an fremden Objekten
const CACHE = Symbol('cache');
const user = { name: 'Anna', age: 31 };
user[CACHE] = { loadedAt: Date.now() };
// Symbol-Schlüssel bleiben für Keys und JSON unsichtbar
console.log(Object.keys(user));
console.log(JSON.stringify(user));
console.log(Object.getOwnPropertySymbols(user));
Symbole als Enum-Werte
const Status = Object.freeze({
IDLE: Symbol('idle'),
LOADING: Symbol('loading'),
DONE: Symbol('done')
});
const render = (status) => {
switch (status) {
case Status.LOADING: return 'Lade …';
case Status.DONE: return 'Fertig';
default: return 'Bereit';
}
};
console.log(render(Status.LOADING));
console.log(render('loading')); // String passt nicht zufällig
Lokales Symbol vs. globale Registry
const local = Symbol('app.token');
const global1 = Symbol.for('app.token');
const global2 = Symbol.for('app.token');
console.log(local === global1);
console.log(global1 === global2);
console.log(Symbol.keyFor(global1));
console.log(Symbol.keyFor(local));
// Wichtig · Fallstricke
new Symbol()wirft einenTypeError. Rufen SieSymbol()immer ohnenewauf. Ein Wrapper-Objekt bekommen Sie bei Bedarf mitObject(sym).- Keine automatische Umwandlung in einen String:
'x' + symund`${sym}`werfen einenTypeError. Nutzen Sie ausdrücklichString(sym),sym.toString()odersym.description. Auch+sym(Umwandlung in eine Zahl) wirft einen Fehler. - Nicht wirklich privat: Über
Object.getOwnPropertySymbols()undReflect.ownKeys()bleiben Symbol-Eigenschaften erreichbar. Echte Kapselung bieten private Klassenfelder (#feld). - JSON:
JSON.stringify()übergeht Symbol-Schlüssel. Symbol-Werte werden in Objekten weggelassen und in Arrays zunull. - Realms: Mit
Symbol()erzeugte Symbole sind in iframes oder Workern nicht dieselben. Dafür gibt esSymbol.for(). - Kompatibilität: Unterstützt in allen modernen Browsern und in Node.js, nicht im Internet Explorer.
descriptiongibt es erst seit ES2019.