Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Erläuterung des Symboltyps in Javascript

Detaillierte Erläuterung des Symboltyps in Javascript

黄舟
黄舟Original
2017-08-08 14:06:002861Durchsuche


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.

Symbole

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.

Versteckte Eigenschaften

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 key
Stellen 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")

Der Code lautet wie folgt:

// ...
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 Symbol

Wenn 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] ); // 123
Es 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 Symbol

Normalerweise 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.

wird in der Registrierung erstellt oder gelesen. Die Verwendungssyntax lautet:

symbol.for(name)

Das Symbol in der Registrierung wird als globales Symbol bezeichnet Anwendungsweites Symbol. Der Code ist zugänglich und globale Symbole können verwendet werden.
// 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

Für globale Symbole gibt

nicht nur das Symbol basierend auf dem Namen zurück, sondern hat auch den umgekehrten Aufruf:

, der die entgegengesetzte Funktion hat: zurückgibt der Name basiert auf dem globalen Symbol. Symbol.for(name)Beispiel: Symbol.keyFor(name)

Symbol.keyfor ist intern implementiert, verwendet die globale Symbolregistrierung und sucht nach Symbolnamen basierend auf dem Symbol.
let sym = Symbol.for("name");
let sym2 = Symbol.for("id");

// get name from symbol
alert( Symbol.keyFor(sym) ); // name
alert( Symbol.keyFor(sym2) ); // id
Es 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:

Nicht globales Symbol, der Name wird nur für Debugging-Zwecke verwendet.
alert( Symbol.keyFor(Symbol.for("name")) ); // name, global symbol

alert( Symbol.keyFor(Symbol("name2")) ); // undefined, non-global symbol

Systemsymbole

In Javascript gibt es viele Systemsymbole, mit denen wir verschiedene Aspekte des Objekts anpassen können.

Hier sind einige häufig verwendete Symbole:


    Symbol.hasInstance
  • Symbol.isConcatSpreadable
  • Symbol.iterator
  • Symbol.toPrimitive
  • Beispiel:
Wird zur Beschreibung von Objekten beim Konvertieren von Objekten in Basistypen verwendet. Wenn Sie sich weiter intensiv mit Javascript befassen, werden Sie sich nach und nach mit den anderen vertraut machen.

Symbol.toPrimitiveZusammenfassung

    Symbol ist ein Basistyp, der eine eindeutige Identifizierung implementiert
  • Symbol erstellen
  • 🎜>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 verwenden
  • Symbol erscheint nicht im for ..im Ergebnis
  • Die mit symbol(name) erstellten Symbole sind immer unterschiedlich, auch wenn die Namen gleich sind. Wenn Sie möchten, dass Symbole mit demselben Namen gleich sind, verwenden Sie die globale Registrierung
  • symbol.for(name), um ein globales Symbol mit einem bestimmten Namen zurückzugeben, und mehrere Aufrufe, um dasselbe zurückzugeben symbol
  • Javascript verfügt über Systemsymbole, auf die über Symbol.* zugegriffen werden kann. Wir können sie verwenden, um einige integrierte Verhaltensweisen zu ändern.

Technisch 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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn