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 einen symbol
primitive zurückgibt – auch als Symbolwert oder einfach nur Symbol bezeichnet –, das garantiert einzigartig ist. Symbole werden häufig verwendet, um einzigartigen Eigenschaftsschlüsseln zu einem Objekt hinzuzufügen, die nicht mit Schlüsseln kollidieren, die anderer Code möglicherweise dem Objekt hinzufügt, und die vor jeglichen Mechanismen versteckt sind, die anderer Code typischerweise verwendet, um auf das Objekt zuzugreifen. Dies ermöglicht eine Form der schwachen 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 das gleiche Symbol für einen gegebenen Wert von "key"
zurückgeben. Wenn Symbol.for("key")
aufgerufen wird und ein Symbol mit dem gegebenen Schlüssel im globalen Symbolregister gefunden werden kann, wird dieses Symbol zurückgegeben. Andernfalls wird ein neues Symbol erstellt, im globalen Symbolregister unter dem gegebenen Schlüssel hinzugefügt und zurückgegeben.
Beschreibung
Um ein neues primitives Symbol zu erstellen, schreibt man Symbol()
mit einem optionalen String als Beschreibung:
const sym1 = Symbol();
const sym2 = Symbol("foo");
const sym3 = Symbol("foo");
Der obige Code erstellt drei neue Symbole. Beachten Sie, dass Symbol("foo")
den String "foo"
nicht in ein Symbol umwandelt. Es erstellt jedes Mal ein neues Symbol:
Symbol("foo") === Symbol("foo"); // false
Die folgende Syntax mit dem new
-Operator wirft einen TypeError
:
const sym = new Symbol(); // TypeError
Dies verhindert, dass Autoren ein explizites Symbol
-Wrapper-Objekt statt eines neuen Symbolwerts erstellen, was überraschen könnte, da das Erstellen expliziter Wrapper-Objekte um primitive Datentypen allgemein 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 hat (das heißt, Sie können das gleiche Symbol nicht zweimal erstellen), verhalten sie sich in gewisser Weise wie Objekte. Zum Beispiel sind sie speicherbereinigt und können daher in WeakMap
, WeakSet
, WeakRef
und FinalizationRegistry
-Objekten gespeichert werden.
Geteilte Symbole im globalen Symbolregister
Die obige Syntax unter Verwendung der Symbol()
-Funktion erstellt ein Symbol, dessen Wert während der gesamten Lebensdauer des Programms einzigartig bleibt. Um Symbole zu erstellen, die über Dateien hinweg und sogar über verschiedene Bereiche (von denen jeder seinen eigenen globalen Gültigkeitsbereich hat) 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 nicht mit irgendeiner internen Datenstruktur in der JavaScript-Engine übereinstimmen muss – und selbst wenn ein solches Register existiert, ist sein Inhalt JavaScript-Code nicht zugänglich, außer durch die for()
- und keyFor()
-Methoden.
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 entsprechenden String-Schlüssel zurückgibt. Jede Methode ist das Inverse der anderen, sodass Folgendes true
ist:
Symbol.keyFor(Symbol.for("tokenString")) === "tokenString"; // true
Da registrierte Symbole an beliebiger Stelle beliebig erstellt werden können, verhalten sie sich fast genau wie die Strings, die sie umschließen. Daher sind sie nicht garantiert einzigartig und nicht speicherbereinigt. Daher sind registrierte Symbole in WeakMap
, WeakSet
, WeakRef
und FinalizationRegistry
-Objekten nicht erlaubt.
Bekannte Symbole
Alle statischen Eigenschaften des Symbol
-Konstruktors sind selbst Symbole, deren Werte über Bereiche hinweg konstant sind. Sie sind als bekannte Symbole bekannt und sollen als "Protokolle" für bestimmte eingebaute JavaScript-Operationen dienen, die es Benutzern ermöglichen, das Verhalten der Sprache anzupassen. Wenn zum Beispiel eine Konstruktorfunktion eine Methode mit Symbol.hasInstance
als Name hat, kodiert diese Methode ihr Verhalten mit dem instanceof
-Operator.
Vor der Einführung bekannter Symbole verwendete JavaScript normale Eigenschaften, um bestimmte eingebaute Operationen zu implementieren. Zum Beispiel wird die Funktion JSON.stringify
versuchen, die toJSON()
-Methode jedes Objekts aufzurufen, und die String
-Funktion wird die toString()
- und valueOf()
-Methoden des Objekts aufrufen. Da jedoch immer mehr Operationen zur Sprache hinzugefügt werden, könnte die Zuweisung jeder Operation eine "magische Eigenschaft" darstellen, sodass die Rückwärtskompatibilität bricht und das Verhalten der Sprache schwieriger nachvollziehbar wird. Bekannte Symbole ermöglichen es, dass die Anpassungen für normalen Code "unsichtbar" sind, der typischerweise nur String-Eigenschaften liest.
Hinweis:
Die Spezifikation verwendete früher die Notation @@<symbol-name>
, um bekannte Symbole zu kennzeichnen. Beispielsweise wurde Symbol.hasInstance
als @@hasInstance
geschrieben und die Array.prototype[Symbol.iterator]()
-Methode würde als Array.prototype[@@iterator]()
bezeichnet werden. Diese Notation wird in der Spezifikation nicht mehr verwendet, aber Sie können sie dennoch in älterer Dokumentation oder Diskussionen sehen.
Bekannte Symbole haben kein Konzept der Speicherbereinigbarkeit, da sie in einer festen Menge vorkommen und während der gesamten Lebensdauer 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 Symboleigenschaften auf Objekten
Die Methode Object.getOwnPropertySymbols()
gibt ein Array von Symbolen zurück und ermöglicht es Ihnen, Symboleigenschaften auf einem gegebenen Objekt zu finden. Beachten Sie, dass jedes Objekt mit keinen eigenen Symboleigenschaften initialisiert wird, sodass dieses Array leer sein wird, es sei denn, Sie haben Symboleigenschaften auf dem Objekt gesetzt.
Konstruktor
Symbol()
-
Gibt primitive Werte des Typs Symbol zurück. Wirft einen Fehler, wenn mit
new
aufgerufen.
Statische Eigenschaften
Die statischen Eigenschaften sind allesamt bekannte Symbole. In den Beschreibungen dieser Symbole werden wir Formulierungen wie „Symbol.hasInstance
ist eine Methode, die bestimmt...“ verwenden, aber bedenken Sie, dass damit die Semantik einer Objektmethode gemeint ist, die dieses Symbol als Methodennamen hat (weil bekannte Symbole als „Protokolle“ fungieren), nicht der Wert des Symbols selbst.
Symbol.asyncIterator
-
Eine Methode, die den standardmäßigen AsyncIterator für ein Objekt zurückgibt. Wird von
for await...of
verwendet. Symbol.hasInstance
-
Eine Methode, die bestimmt, ob ein Konstruktorobjekt ein Objekt als seine Instanz erkennt. Wird von
instanceof
verwendet. Symbol.isConcatSpreadable
-
Ein Boolescher Wert, der angibt, ob ein Objekt auf seine Array-Elemente abgeflacht werden soll. Wird von
Array.prototype.concat()
verwendet. Symbol.iterator
-
Eine Methode, die den standardmäßigen Iterator für ein Objekt zurückgibt. Wird von
for...of
verwendet. Symbol.match
-
Eine Methode, die gegen einen String abgleicht und auch verwendet wird, um zu bestimmen, ob ein Objekt als regulärer Ausdruck verwendet werden kann. Wird von
String.prototype.match()
verwendet. Symbol.matchAll
-
Eine Methode, die einen Iterator zurückgibt, der Übereinstimmungen des regulären Ausdrucks gegen einen String liefert. Wird von
String.prototype.matchAll()
verwendet. Symbol.replace
-
Eine Methode, die übereinstimmende Teilstrings eines Strings ersetzt. Wird von
String.prototype.replace()
verwendet. Symbol.search
-
Eine Methode, die den Index innerhalb eines Strings zurückgibt, der dem regulären Ausdruck entspricht. Wird von
String.prototype.search()
verwendet. Symbol.species
-
Eine Konstruktorfunktion, die verwendet wird, um abgeleitete Objekte zu erstellen.
Symbol.split
-
Eine Methode, die einen String an den Indizes trennt, die einem regulären Ausdruck entsprechen. Wird von
String.prototype.split()
verwendet. 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. Wird von
Object.prototype.toString()
verwendet. 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 gegebenen
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 gegebene 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
-
Ein schreibgeschützter String, der die Beschreibung des Symbols enthält.
Symbol.prototype[Symbol.toStringTag]
-
Der Anfangswert der
[Symbol.toStringTag]
-Eigenschaft ist der String"Symbol"
. Diese Eigenschaft wird inObject.prototype.toString()
verwendet. DaSymbol
jedoch auch über seine eigenetoString()
-Methode verfügt, wird diese Eigenschaft nicht verwendet, es sei denn, Sie rufenObject.prototype.toString.call()
mit einem Symbol alsthisArg
auf.
Instanz-Methoden
Symbol.prototype.toString()
-
Gibt einen String zurück, der 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-Typ-Konvertierungen
Einige Punkte, die beim Arbeiten mit der Typkonvertierung von Symbolen zu beachten sind.
- Beim Versuch, ein Symbol in eine Zahl zu konvertieren, wird ein
TypeError
geworfen (z.B.+sym
odersym | 0
). - Beim Verwenden von losem Gleichnis ergibt
Object(sym) == sym
true
. Symbol("foo") + "bar"
wirft einTypeError
(kann Symbol nicht in String konvertieren). Dies verhindert, dass Sie stillschweigend einen neuen Eigenschaftsnamen für einen String aus einem Symbol erstellen, zum Beispiel.- Die "sichere"
String(sym)
-Konvertierung funktioniert wie ein Aufruf vonSymbol.prototype.toString()
bei Symbolen, aber beachten Sie, dassnew String(sym)
einen Fehler werfen wird.
Symbole und for...in-Iterationen
Symbole sind in for...in
-Iterationen nicht aufzählbar. Darüber hinaus wird Object.getOwnPropertyNames()
keine Symbol-Objekteigenschaften zurückgeben, aber Sie können 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()
Symbol-schlüsselwerte Eigenschaften werden bei der Verwendung von JSON.stringify()
vollständig ignoriert:
JSON.stringify({ [Symbol("foo")]: "foo" });
// '{}'
Für weitere Einzelheiten siehe JSON.stringify()
.
Symbol-Wrapper-Objekte als Eigenschaftsschlüssel
Wenn ein Symbol-Wrapper-Objekt als Eigenschaftsschlüssel verwendet wird, wird dieses Objekt auf sein enthaltenes Symbol geleitet:
const sym = Symbol("foo");
const obj = { [sym]: 1 };
obj[sym]; // 1
obj[Object(sym)]; // still 1
Spezifikationen
Specification |
---|
ECMAScript® 2025 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)