Signatur
Beschreibung
Die Methode Symbol.prototype[Symbol.toPrimitive]() legt fest, wie ein Symbol-Objekt in einen primitiven Wert umgewandelt wird. Sie gibt immer den zugrunde liegenden primitiven Symbolwert zurück, egal welcher hint ("string", "number" oder "default") übergeben wird.
Direkt aufrufen muss man sie so gut wie nie. JavaScript ruft sie intern über die abstrakte Operation ToPrimitive auf, sobald ein Wrapper-Objekt (erzeugt mit Object(sym)) in einen primitiven Wert umgewandelt werden soll, etwa beim losen Vergleich mit ==. Bei primitiven Symbolen wird die Methode nicht aufgerufen, weil diese schon primitiv sind.
Wichtig: Die Methode gibt ein Symbol zurück und keine Zeichenkette und keine Zahl. Jede weitere implizite Umwandlung in einen String oder eine Zahl, z. B. in Template-Literalen, mit + oder mit String(wrapper), wirft deshalb einen TypeError. Für eine lesbare Darstellung verwendet man Symbol.prototype.toString() oder Symbol.prototype.description.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $hint | "string" | "number" | "default" | Gewünschter Zieltyp der Umwandlung. Wird von dieser Methode ignoriert, das Ergebnis ist immer der Symbolwert. |
Rückgabewert
this. Ist this weder ein Symbol noch ein Symbol-Wrapper-Objekt, wird ein TypeError geworfen.Beispiele
Direkter Aufruf: hint spielt keine Rolle
const id = Symbol("id");
console.log(id[Symbol.toPrimitive]("string") === id);
console.log(id[Symbol.toPrimitive]("number") === id);
console.log(typeof id[Symbol.toPrimitive]("default"));
Wrapper-Objekt beim losen Vergleich
const token = Symbol("token");
const wrapper = Object(token); // Symbol-Wrapper-Objekt
console.log(typeof wrapper); // "object"
// == ruft intern wrapper[Symbol.toPrimitive]("default") auf
console.log(wrapper == token);
console.log(wrapper === token); // unterschiedliche Typen
console.log(wrapper.valueOf() === token);
Fallstrick: Umwandlung in einen String schlägt fehl
const wrapper = Object(Symbol("user"));
try {
// ToPrimitive liefert ein Symbol, das sich nicht implizit in einen String umwandeln lässt
console.log(`Schlüssel: ${wrapper}`);
} catch (err) {
console.log(err.constructor.name);
}
// Sichere Alternativen:
console.log(wrapper.toString());
console.log(wrapper.description);
Falsches this wirft einen TypeError
const toPrim = Symbol.prototype[Symbol.toPrimitive];
try {
toPrim.call("kein Symbol", "default");
} catch (err) {
console.log(err instanceof TypeError);
}
console.log(Object.getOwnPropertyDescriptor(Symbol.prototype, Symbol.toPrimitive));
// Wichtig · Fallstricke
- Ergebnis bleibt ein Symbol: Template-Literale,
wrapper + "",+wrapperund auchString(wrapper)werfen bei Wrapper-Objekten einenTypeError. Nur bei primitiven Symbolen liefertString(sym)ausnahmsweise"Symbol(beschreibung)". - Eigenschaftsattribute: Die Eigenschaft ist
writable: false,enumerable: falseundconfigurable: true. Eine einfache Zuweisung ändert sie also nicht (im Strict Mode gibt es einenTypeError), mitObject.definePropertylässt sie sich aber überschreiben. Davon ist abzuraten, weil sich dann Vergleiche wieObject(sym) == symanders verhalten. - Wrapper-Objekte vermeiden:
new Symbol()wirft einenTypeError. Wrapper entstehen nur überObject(sym)und sind in der Praxis selten sinnvoll. - Kompatibilität: Wird von allen modernen Browsern und von Node.js (ab 6) unterstützt. Der Internet Explorer unterstützt es nicht.