In diesem Beitrag geht es um die Symbol()
, mit tatsächlichen Beispielen, die ich finden / machen konnte, und Fakten und Definitionen, die ich finden konnte.
TLDR;
Dies Symbol()
ist der Datentyp, der mit der Veröffentlichung von ECMAScript 6 (ES6) eingeführt wurde.
Es gibt zwei merkwürdige Fakten über das Symbol.
Der erste Datentyp und der einzige Datentyp in JavaScript, der kein Literal enthält
Jede Variable, die mit definiert ist Symbol()
, erhält eindeutigen Inhalt, ist jedoch nicht wirklich privat .
Alle Daten haben ein eigenes Symbol, und für dieselben Daten wären die Symbole dieselben . Weitere Informationen im folgenden Absatz, ansonsten handelt es sich nicht um eine TLRD. :) :)
Wie initialisiere ich das Symbol?
1. Um eine eindeutige Kennung mit einem debuggbaren Wert zu erhalten
Sie können es entweder so machen:
var mySymbol1 = Symbol();
Oder so:
var mySymbol2 = Symbol("some text here");
Das "some text here"
Zeichenfolge kann nicht aus dem Symbol extrahiert werden, sondern ist nur eine Beschreibung für Debugging-Zwecke. Es ändert in keiner Weise das Verhalten des Symbols. Obwohl Sie es könnten console.log
(was fair ist, da der Wert für das Debuggen ist, um dieses Protokoll nicht mit einem anderen Protokolleintrag zu verwechseln):
console.log(mySymbol2);
// Symbol(some text here)
2. Um ein Symbol für einige Zeichenfolgendaten zu erhalten
In diesem Fall wird der Wert des Symbols tatsächlich berücksichtigt, und auf diese Weise können zwei Symbole nicht eindeutig sein.
var a1 = Symbol.for("test");
var a2 = Symbol.for("test");
console.log(a1 == a2); //true!
Nennen wir diese Symbole "Symbole vom zweiten Typ". Sie überschneiden sich nicht mit den Symbolen des "ersten Typs" (dh denjenigen, die mit definiert sindSymbol(data)
in keiner Weise ).
Die nächsten beiden Absätze beziehen sich nur auf die Symbol ersten Typ .
Wie profitiere ich von der Verwendung von Symbol anstelle der älteren Datentypen?
Betrachten wir zunächst ein Objekt, einen Standarddatentyp. Wir könnten dort einige Schlüssel-Wert-Paare definieren und durch Angabe des Schlüssels auf die Werte zugreifen.
var persons = {"peter":"pan","jon":"doe"};
console.log(persons.peter);
// pan
Was ist, wenn wir zwei Personen mit dem Namen Peter haben?
Dies tun:
var persons = {"peter":"first", "peter":"pan"};
würde nicht viel Sinn machen.
Es scheint also ein Problem von zwei absolut unterschiedlichen Personen mit demselben Namen zu sein. Lassen Sie uns dann neu verweisen Symbol()
. Es ist wie eine Person im wirklichen Leben - jede Person ist einzigartig , aber ihre Namen können gleich sein. Definieren wir zwei "Personen".
var a = Symbol("peter");
var b = Symbol("peter");
Jetzt haben wir zwei verschiedene Personen mit dem gleichen Namen. Sind unsere Personen wirklich anders? Sie sind; Sie können dies überprüfen:
console.log(a == b);
// false
Wie profitieren wir dort?
Wir können zwei Einträge in Ihrem Objekt für die verschiedenen Personen vornehmen, und sie können in keiner Weise verwechselt werden.
var firstPerson = Symbol("peter");
var secondPerson = Symbol("peter");
var persons = {[firstPerson]:"first", [secondPerson]:"pan"};
Hinweis:
Es ist jedoch zu beachten, dass beim Stringing des Objekts JSON.stringify
alle Paare gelöscht werden, die mit einem Symbol als Schlüssel initialisiert wurden.
Beim Ausführen Object.keys
werden solche Symbol()->value
Paare auch nicht zurückgegeben.
Mit dieser Initialisierung ist es absolut unmöglich, die Einträge mit der ersten und zweiten Person zu verwechseln. Wenn Sie console.log
nach ihnen rufen, werden ihre zweiten Namen korrekt ausgegeben.
console.log(persons[a]);
// first
console.log(persons[b]);
// pan
Wie unterscheidet es sich bei der Verwendung in Objekten von der Definition nicht aufzählbarer Eigenschaften?
In der Tat gab es bereits eine Möglichkeit, eine zu versteckende Eigenschaft Object.keys
und eine Aufzählung zu definieren . Hier ist es:
var anObject = {};
var fruit = "apple";
Object.defineProperty( anObject, fruit, {
enumerable: false,
value: "green"
});
Welchen Unterschied Symbol()
bringt es dort? Der Unterschied besteht darin, dass Sie die Eigenschaft weiterhin Object.defineProperty
auf die übliche Weise definieren können:
console.log(anObject[fruit]); //green
console.log(anObject["apple"]); //green
console.log(anObject.apple); //green
Und wenn mit Symbol wie im vorherigen Absatz definiert:
fruit = Symbol("apple");
Sie können den Wert nur erhalten, wenn Sie die Variable kennen, d. H.
console.log(anObject[fruit]); //green
console.log(anObject["apple"]); //undefined
console.log(anObject.apple); //undefined
"apple"
Wenn Sie eine andere Eigenschaft unter dem Schlüssel definieren, wird das ältere Objekt gelöscht (und wenn es fest codiert ist, kann es einen Fehler auslösen). Also keine Äpfel mehr! Das ist schade. Unter Bezugnahme auf den vorherigen Absatz sind die Symbole eindeutig und definieren einen Schlüssel Symbol()
, der ihn eindeutig macht.
Typkonvertierung und -prüfung
Im Gegensatz zu anderen Datentypen ist es unmöglich, den Symbol()
in einen anderen Datentyp zu konvertieren .
Es ist möglich, ein Symbol basierend auf dem primitiven Datentyp durch Aufrufen zu "erstellen" Symbol(data)
.
An der Überprüfung des Typs ändert sich nichts.
function isSymbol ( variable ) {
return typeof someSymbol === "symbol";
}
var a_Symbol = Symbol("hey!");
var totally_Not_A_Symbol = "hey";
console.log(isSymbol(a_Symbol)); //true
console.log(isSymbol(totally_Not_A_Symbol)); //false