Start · Sprachen · JavaScript · Referenz · Symbol.prototype[Symbol.toPrimitive]()

Symbol.prototype[Symbol.toPrimitive]()

Methode

Gibt den primitiven Symbolwert eines Symbols oder eines <code>Symbol</code>-Wrapper-Objekts zurück. Das Argument <code>hint</code> wird dabei ignoriert.

seit JavaScript ES2015 Kategorie: method-property

Signatur

Symbol.prototype[Symbol.toPrimitive](hint)

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

Typ
symbol
Beschreibung
Der primitive Symbolwert von 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"));
true true symbol

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);
object true false true

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);
TypeError Symbol(user) user

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));
true { value: [Function: [Symbol.toPrimitive]], writable: false, enumerable: false, configurable: true }

// Wichtig · Fallstricke

  • Ergebnis bleibt ein Symbol: Template-Literale, wrapper + "", +wrapper und auch String(wrapper) werfen bei Wrapper-Objekten einen TypeError. Nur bei primitiven Symbolen liefert String(sym) ausnahmsweise "Symbol(beschreibung)".
  • Eigenschaftsattribute: Die Eigenschaft ist writable: false, enumerable: false und configurable: true. Eine einfache Zuweisung ändert sie also nicht (im Strict Mode gibt es einen TypeError), mit Object.defineProperty lässt sie sich aber überschreiben. Davon ist abzuraten, weil sich dann Vergleiche wie Object(sym) == sym anders verhalten.
  • Wrapper-Objekte vermeiden: new Symbol() wirft einen TypeError. Wrapper entstehen nur über Object(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.