Heim >Web-Frontend >js-Tutorial >Detaillierte Erläuterung des Symboltyps in Javascript
Gemäß der Spezifikation können Objektattributschlüssel nur vom Typ String oder Symbol sein, nicht vom Typ Zahl oder Boolescher Wert, sondern nur vom Typ String und Es gibt zwei Arten von Symbolen.
Normalerweise vergleichen wir Attributzeichenfolgen. Schauen wir uns nun die Vorteile an, die uns der Symboltyp bietet.
Der Wert „Symbol“ stellt eine eindeutige Kennung unter Verwendung des angegebenen Namens dar. Werte dieser Art können wie folgt erstellt werden: Symbol(name)
:
// id is a symbol with the name "id" let id = Symbol("id");
Symbole sorgen für Einzigartigkeit und erzeugen unterschiedliche Werte, selbst wenn wir denselben Namen verwenden. Hier sind zum Beispiel zwei Symbole mit demselben Namen, beide sind nicht gleich:
let id1 = Symbol("id"); let id2 = Symbol("id"); alert(id1 == id2); // false
Wenn Sie mit Ruby oder anderen Sprachen vertraut sind, gibt es die gleiche Art von Symbolen, lassen Sie sich nicht irreführen, Javascript-Symbole sind unterschiedlich.
Symbol ermöglicht die Erstellung versteckter Eigenschaften eines Objekts, damit anderer Code nicht versehentlich darauf zugreift oder diese überschreibt.
Wenn wir beispielsweise den „Identifikator“ des Objektbenutzers speichern möchten, können wir ein Symbol der ID erstellen:
Let user = { name: „John“ };
Sei id = Symbol(“id”);
user[id] = "ID Value"; alert( user[id] ); // we can access the data using the symbol as the keyStellen wir uns nun vor, dass ein anderes Skript dem Benutzerobjekt sein eigenes „id“-Attribut für eigene Zwecke hinzufügen möchte. Da es sich möglicherweise um eine andere Javascript-Bibliothek handelt, kennen sie sich überhaupt nicht.
Kein Problem, Sie können Ihr eigenes
erstellen. Symbol("id")
// ... let id = Symbol("id"); user[id] = "Their id value";Das ist konfliktfrei, da die Symbole immer unterschiedlich sind, auch bei gleichem Namen. Beachten Sie, dass es zu einem Konflikt kommt, wenn wir die Zeichenfolge „id“ anstelle des Symbols verwenden, um denselben Zweck zu erreichen:
let user = { name: "John" }; // our script uses "id" property user.id = "ID Value"; // ...if later another script the uses "id" for its purposes... user.id = "Their id value" // boom! overwritten! it did not mean to harm the colleague, but did it!Literal verwendet SymbolWenn wir Symbol in einem Literal verwenden Objekt, Wir müssen eckige Klammern verwenden:
let id = Symbol("id"); let user = { name: "John", [id]: 123 // not just "id: 123" };, da wir den Wert der Symbolvariablen mit dem Namen „id“ benötigen, nicht die Zeichenfolge „id“. Symbol wird von for...in ignoriert Das Symbolattribut nimmt nicht an der for..in-Schleife teil, zum Beispiel:
let id = Symbol("id"); let user = { name: "John", age: 30, [id]: 123 }; for(let key in user) alert(key); // name, age (no symbols) // the direct access by the symbol works alert( "Direct: " + user[id] );Zu diesem Zeitpunkt , ein Teil des Konzepts ist im Allgemeinen verborgen, wenn andere Skripte oder Bibliotheken keinen Zugriff auf die Symboleigenschaft erwarten.
Im Gegensatz dazu kopiert Object.assign sowohl Zeichenattribute als auch Symbolattribute.
let id = Symbol("id"); let user = { [id]: 123 }; let clone = Object.assign({}, user); alert( clone[id] ); // 123Es gibt keinen Widerspruch zwischen den beiden. So ist die Spezifikation konzipiert. Die Idee ist, dass wir beim Klonen oder Zusammenführen von Objekten normalerweise auch das Symbolattribut kopieren möchten. Andere Arten von Attributschlüsseln müssen zwangsweise in Zeichenfolgen konvertiert werden: Schlüssel in Objekten können nur Zeichenfolgen oder Symbole verwenden, und andere Typen müssen zwangsweise in Zeichenfolgen konvertiert werden.
let obj = { 0: "test" // same as "0": "test" } // both alerts access the same property (the number 0 is converted to string "0") alert( obj["0"] ); // test alert( obj[0] ); // test (same property)Globales SymbolNormalerweise sind alle Symbole unterschiedlich, aber manchmal möchten wir, dass Symbole mit demselben Substantiv gleich sind. Wenn wir beispielsweise in verschiedenen Teilen der Anwendung auf das Symbol mit dem Substantiv „id“ zugreifen möchten, muss es natürlich dasselbe sein.
Dies kann durch die globale Symbolregistrierung erreicht werden. Wir können sie zuerst erstellen und dann darauf zugreifen und sicherstellen, dass das gleiche Symbol durch wiederholten Zugriff mit demselben Substantiv erhalten wird.
symbol.for(name)
// read from the global registry let name = Symbol.for("name"); // if the symbol did not exist, it is created // read it again let nameAgain = Symbol.for("name"); // the same symbol alert( name === nameAgain ); // true
In anderen Programmiersprachen wie Ruby hat jedes Substantiv ein einzelnes Symbol. In JavaScript wissen wir, dass es das globale Symbol ist.
Symbol.keyFor
, der die entgegengesetzte Funktion hat: zurückgibt der Name basiert auf dem globalen Symbol. Symbol.for(name)
Beispiel: Symbol.keyFor(name)
let sym = Symbol.for("name"); let sym2 = Symbol.for("id"); // get name from symbol alert( Symbol.keyFor(sym) ); // name alert( Symbol.keyFor(sym2) ); // idEs hat also keine Auswirkung auf nicht-globale Symbole. Wenn es sich nicht um ein globales Symbol handelt, wird es nicht gefunden und undefiniert zurückgegeben.
Beispiel:
alert( Symbol.keyFor(Symbol.for("name")) ); // name, global symbol alert( Symbol.keyFor(Symbol("name2")) ); // undefined, non-global symbol
Systemsymbole
Symbol.toPrimitive
Zusammenfassung
symbol(name)
Wir erstellen ein Feld, das nur für Personen zugänglich ist, die das entsprechende Symbol kennen. Es ist nützlich, das Symbol zu verwendenTechnisch gesehen sind Symbole nicht zu 100 % verborgen. Es gibt integrierte Methoden Object.getOwnPropertySymbols(obj)
, um alle Symbole abzurufen.
Es gibt auch eine Methode Reflect.ownKeys(obj)
, die alle Schlüssel des Objekts zurückgibt, einschließlich Symbol.
Es ist also nicht wirklich versteckt. Die meisten in Bibliotheken integrierten Methoden und Syntaxkonstrukte folgen jedoch der allgemeinen Konvention, dass sie ausgeblendet sind. Wenn jemand die oben genannte Methode explizit aufruft, versteht er möglicherweise vollständig, was er tut.
Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des Symboltyps in Javascript. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!