Symbol
Baseline Widely available *
This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.
* Some parts of this feature may have varying levels of support.
Symbol
ist ein eingebautes Objekt, dessen Konstruktor ein symbol
Primitiv zurückgibt - auch Symbolwert oder einfach Symbol genannt -, das garantiert einzigartig ist. Symbole werden häufig verwendet, um einem Objekt eindeutige Eigenschaftsschlüssel hinzuzufügen, die nicht mit Schlüsseln kollidieren, die anderer Code dem Objekt hinzufügen könnte, und die vor allen Mechanismen verborgen sind, die anderer Code typischerweise zur Zugriffssteuerung auf das Objekt verwendet. Dies ermöglicht eine schwache Form der Kapselung oder eine schwache Form der Informationsverbergung.
Jeder Aufruf von Symbol()
garantiert die Rückgabe eines einzigartigen Symbols. Jeder Aufruf von Symbol.for("key")
wird immer dasselbe Symbol für einen bestimmten Wert von "key"
zurückgeben. Wenn Symbol.for("key")
aufgerufen wird, wird, wenn ein Symbol mit dem angegebenen Schlüssel im globalen Symbolregister gefunden werden kann, dieses Symbol zurückgegeben. Andernfalls wird ein neues Symbol erstellt, dem globalen Symbolregister unter dem angegebenen Schlüssel hinzugefügt und zurückgegeben.
Beschreibung
Um ein neues primitives Symbol zu erzeugen, schreiben Sie Symbol()
mit einem optionalen String als Beschreibung:
const sym1 = Symbol();
const sym2 = Symbol("foo");
const sym3 = Symbol("foo");
Der obige Code erzeugt drei neue Symbole. Beachten Sie, dass Symbol("foo")
den String "foo"
nicht in ein Symbol umwandelt. Es erzeugt jedes Mal ein neues Symbol:
Symbol("foo") === Symbol("foo"); // false
Die folgende Syntax mit dem new
-Operator wird einen TypeError
auslösen:
const sym = new Symbol(); // TypeError
Dies verhindert, dass Autoren ein explizites Symbol
-Wrapper-Objekt anstelle eines neuen Symbolwertes erstellen, und könnte überraschend sein, da die Erstellung expliziter Wrapper-Objekte um primitive Datentypen im Allgemeinen möglich ist (zum Beispiel new Boolean
, new String
und new Number
).
Wenn Sie wirklich ein Symbol
-Wrapper-Objekt erstellen möchten, können Sie die Object()
-Funktion verwenden:
const sym = Symbol("foo");
typeof sym; // "symbol"
const symObj = Object(sym);
typeof symObj; // "object"
Da Symbole der einzige primitive Datentyp sind, der eine Referenzidentität besitzt (das heißt, Sie können dasselbe Symbol nicht zweimal erstellen), verhalten sie sich in gewisser Weise wie Objekte. Beispielsweise sind sie sammelbar und können daher in WeakMap
, WeakSet
, WeakRef
und FinalizationRegistry
-Objekten gespeichert werden.
Geteilte Symbole im globalen Symbolregister
Die oben genannte Syntax unter Verwendung der Symbol()
-Funktion wird ein Symbol erstellen, dessen Wert während der gesamten Laufzeit des Programms einzigartig bleibt. Um Symbole zu erstellen, die über Dateien und sogar über Bereiche (von denen jeder seinen eigenen globalen Geltungsbereich hat) hinweg verfügbar sind, verwenden Sie die Methoden Symbol.for()
und Symbol.keyFor()
, um Symbole im globalen Symbolregister zu setzen und abzurufen.
Beachten Sie, dass das "globale Symbolregister" nur ein fiktives Konzept ist und möglicherweise keiner internen Datenstruktur in der JavaScript-Engine entspricht - und selbst wenn ein solches Register existiert, ist sein Inhalt außer über die for()
- und keyFor()
-Methoden nicht für den JavaScript-Code verfügbar.
Die Methode Symbol.for(tokenString)
nimmt einen String-Schlüssel und gibt einen Symbolwert aus dem Register zurück, während Symbol.keyFor(symbolValue)
einen Symbolwert nimmt und den String-Schlüssel zurückgibt, der ihm entspricht. Jede ist die Umkehrung der anderen, sodass das folgende wahr ist:
Symbol.keyFor(Symbol.for("tokenString")) === "tokenString"; // true
Da registrierte Symbole beliebig überall erstellt werden können, verhalten sie sich fast genau wie die Strings, die sie ummanteln. Daher sind sie nicht garantiert einzigartig und nicht sammelbar. Deshalb sind registrierte Symbole in WeakMap
, WeakSet
, WeakRef
, und FinalizationRegistry
-Objekten nicht erlaubt.
Bekanntgemachte Symbole
Alle statischen Eigenschaften des Symbol
-Konstruktors sind selbst Symbole, deren Werte über Bereiche hinweg konstant sind. Sie sind als bekanntgemachte Symbole bekannt und dienen als "Protokolle" für bestimmte eingebaute JavaScript-Operationen, die es Benutzern ermöglichen, das Verhalten der Sprache anzupassen. Wenn zum Beispiel eine Konstruktorfunktion eine Methode mit Symbol.hasInstance
als Namen hat, kodiert diese Methode ihr Verhalten mit dem instanceof
-Operator.
Vor den bekanntgemachten Symbolen verwendete JavaScript normale Eigenschaften, um bestimmte eingebaute Operationen zu implementieren. Beispielsweise wird die Funktion JSON.stringify
versuchen, die toJSON()
-Methode eines jeden Objekts aufzurufen, und die Funktion String
ruft die Methoden toString()
und valueOf()
des Objekts auf. Allerdings kann die Benennung jeder Operation als "magische Eigenschaft" mit wachsendem Funktionsumfang der Sprache die Abwärtskompatibilität gefährden und das Verhalten der Sprache schwerer nachvollziehbar machen. Bekanntgemachte Symbole erlauben es, Anpassungen "unsichtbar" vom normalen Code zu halten, der typischerweise nur String-Eigenschaften liest.
Hinweis:
Die Spezifikation verwendete früher die Notation @@<symbol-name>
, um bekanntgemachte Symbole zu bezeichnen. Zum Beispiel wurde Symbol.hasInstance
als @@hasInstance
geschrieben, und die Array.prototype[Symbol.iterator]()
-Methode würde als Array.prototype[@@iterator]()
bezeichnet. Diese Notation wird in der Spezifikation nicht mehr verwendet, aber Sie könnten sie dennoch in älterer Dokumentation oder Diskussionen finden.
Bekanntgemachte Symbole haben nicht das Konzept der Sammelbarkeit, da sie in einer festen Menge vorkommen und während der gesamten Laufzeit des Programms einzigartig sind, ähnlich wie intrinsische Objekte wie Array.prototype
, sodass sie auch in WeakMap
, WeakSet
, WeakRef
, und FinalizationRegistry
-Objekten erlaubt sind.
Finden von Symbol-Eigenschaften auf Objekten
Die Methode Object.getOwnPropertySymbols()
gibt ein Array von Symbolen zurück und ermöglicht es Ihnen, Symbol-Eigenschaften auf einem bestimmten Objekt zu finden. Beachten Sie, dass jedes Objekt ohne eigene Symboleigenschaften initialisiert wird, sodass dieses Array leer ist, es sei denn, Sie haben Symbol-Eigenschaften auf dem Objekt festgelegt.
Konstruktor
Symbol()
-
Gibt primitive Werte des Typs Symbol zurück. Wirft einen Fehler, wenn es mit
new
aufgerufen wird.
Statische Eigenschaften
Die statischen Eigenschaften sind alles bekanntgemachte Symbole. In den Beschreibungen dieser Symbole verwenden wir Sprache wie "Symbol.hasInstance ist eine Methode, die bestimmt...", aber beachten Sie, dass sich dies auf die Semantik der Methode eines Objekts bezieht, die dieses Symbol als Methodennamen hat (da bekanntgemachte Symbole als "Protokolle" fungieren), und nicht den Wert des Symbols selbst beschreibt.
Symbol.asyncIterator
-
Eine Methode, die den Standard-AsyncIterator für ein Objekt zurückgibt. Verwendet von
for await...of
. Symbol.hasInstance
-
Eine Methode, die bestimmt, ob ein Konstruktor-Objekt ein Objekt als seine Instanz erkennt. Verwendet von
instanceof
. Symbol.isConcatSpreadable
-
Ein Boolescher Wert, der angibt, ob ein Objekt auf seine Array-Elemente flachgelegt werden sollte. Verwendet von
Array.prototype.concat()
. Symbol.iterator
-
Eine Methode, die den Standard-Iterator für ein Objekt zurückgibt. Verwendet von
for...of
. Symbol.match
-
Eine Methode, die gegen einen String matched, und auch verwendet wird, um zu bestimmen, ob ein Objekt als regulärer Ausdruck verwendet werden kann. Verwendet von
String.prototype.match()
. Symbol.matchAll
-
Eine Methode, die einen Iterator zurückgibt, der Matches des regulären Ausdrucks gegen einen String liefert. Verwendet von
String.prototype.matchAll()
. Symbol.replace
-
Eine Methode, die übereinstimmende Unterstrings eines Strings ersetzt. Verwendet von
String.prototype.replace()
. Symbol.search
-
Eine Methode, die den Index innerhalb eines Strings zurückgibt, der dem regulären Ausdruck entspricht. Verwendet von
String.prototype.search()
. Symbol.species
-
Eine Konstruktorfunktion, die verwendet wird, um abgeleitete Objekte zu erstellen.
Symbol.split
-
Eine Methode, die einen String an den Indizes aufspaltet, die einem regulären Ausdruck entsprechen. Verwendet von
String.prototype.split()
. Symbol.toPrimitive
-
Eine Methode, die ein Objekt in einen primitiven Wert umwandelt.
Symbol.toStringTag
-
Ein String-Wert, der für die Standardbeschreibung eines Objekts verwendet wird. Verwendet von
Object.prototype.toString()
. Symbol.unscopables
-
Ein Objektwert, dessen eigene und geerbte Eigenschaftsnamen von den
with
-Umgebungsbindungen des zugehörigen Objekts ausgeschlossen sind.
Statische Methoden
Symbol.for()
-
Sucht nach vorhandenen registrierten Symbolen im globalen Symbolregister mit dem angegebenen
key
und gibt es zurück, wenn es gefunden wird. Andernfalls wird ein neues Symbol erstellt und mitkey
registriert. Symbol.keyFor()
-
Ruft einen gemeinsamen Symbolschlüssel aus dem globalen Symbolregister für das angegebene Symbol ab.
Instanz-Eigenschaften
Diese Eigenschaften sind auf Symbol.prototype
definiert und werden von allen Symbol
-Instanzen geteilt.
Symbol.prototype.constructor
-
Die Konstruktorfunktion, die das Instanzobjekt erstellt hat. Für
Symbol
-Instanzen ist der Anfangswert derSymbol
-Konstruktor. Symbol.prototype.description
-
Eine schreibgeschützte Zeichenfolge, die die Beschreibung des Symbols enthält.
Symbol.prototype[Symbol.toStringTag]
-
Der anfängliche Wert der
[Symbol.toStringTag]
-Eigenschaft ist die Zeichenfolge"Symbol"
. Diese Eigenschaft wird inObject.prototype.toString()
verwendet. DaSymbol
jedoch auch eine eigenetoString()
-Methode hat, wird diese Eigenschaft nicht verwendet, es sei denn, Sie rufenObject.prototype.toString.call()
mit einem Symbol alsthisArg
auf.
Instanz-Methoden
Symbol.prototype.toString()
-
Gibt eine Zeichenfolge zurück, die die Beschreibung des Symbols enthält. Überschreibt die
Object.prototype.toString()
-Methode. Symbol.prototype.valueOf()
-
Gibt das Symbol zurück. Überschreibt die
Object.prototype.valueOf()
-Methode. Symbol.prototype[Symbol.toPrimitive]()
-
Gibt das Symbol zurück.
Beispiele
Verwendung des typeof-Operators mit Symbolen
Der typeof
-Operator kann Ihnen helfen, Symbole zu identifizieren.
typeof Symbol() === "symbol";
typeof Symbol("foo") === "symbol";
typeof Symbol.iterator === "symbol";
Symbol-Typkonvertierungen
Einige Dinge zu beachten, wenn Sie mit der Typkonvertierung von Symbolen arbeiten.
- Wenn versucht wird, ein Symbol in eine Zahl zu konvertieren, wird ein
TypeError
ausgelöst (z.B.+sym
odersym | 0
). - Bei lockerer Gleichheit gibt
Object(sym) == sym
true
zurück. Symbol("foo") + "bar"
wirft einTypeError
(Symbol kann nicht in einen String konvertiert werden). Dies verhindert, dass Sie beispielsweise stillschweigend einen neuen String-Eigenschaftsnamen aus einem Symbol erstellen.- Die "sicherere"
String(sym)
-Konvertierung funktioniert wie ein Aufruf vonSymbol.prototype.toString()
mit Symbolen, beachten Sie jedoch, dassnew String(sym)
einen Fehler auslöst.
Symbole und for...in-Iteration
Symbole sind in for...in
-Iterationen nicht aufgezählt. Darüber hinaus wird Object.getOwnPropertyNames()
keine Symbolobjekteigenschaften zurückgeben, jedoch können Sie Object.getOwnPropertySymbols()
verwenden, um diese zu erhalten.
const obj = {};
obj[Symbol("a")] = "a";
obj[Symbol.for("b")] = "b";
obj["c"] = "c";
obj.d = "d";
for (const i in obj) {
console.log(i);
}
// "c" "d"
Symbole und JSON.stringify()
Symbolverankerte Eigenschaften werden beim Verwenden von JSON.stringify()
völlig ignoriert:
JSON.stringify({ [Symbol("foo")]: "foo" });
// '{}'
Für weitere Details siehe JSON.stringify()
.
Symbol-Wrapper-Objekte als Eigenschaftsschlüssel
Wenn ein Symbol-Wrapper-Objekt als Eigenschaftsschlüssel verwendet wird, wird dieses Objekt auf sein ummanteltes Symbol umgewandelt:
const sym = Symbol("foo");
const obj = { [sym]: 1 };
obj[sym]; // 1
obj[Object(sym)]; // still 1
Spezifikationen
Specification |
---|
ECMAScript® 2026 Language Specification # sec-symbol-objects |
Browser-Kompatibilität
Siehe auch
- Polyfill von
Symbol
incore-js
typeof
- JavaScript-Datentypen und Datenstrukturen
- ES6 In Depth: Symbols auf hacks.mozilla.org (2015)