UPDATE : Kürzlich erschien ein brillanter Artikel von Mozilla . Lesen Sie es, wenn Sie neugierig sind.
Wie Sie vielleicht wissen, planen sie, einen neuen primitiven Symboltyp in ECMAScript 6 aufzunehmen (ganz zu schweigen von einigen anderen verrückten Dingen). Ich habe immer gedacht, dass der :symbol
Begriff in Ruby unnötig ist; Wir könnten stattdessen leicht einfache Zeichenfolgen verwenden, wie wir es in JavaScript tun. Und jetzt beschließen sie, die Dinge in JS damit zu komplizieren.
Ich verstehe die Motivation nicht. Könnte mir jemand erklären, ob wir wirklich Symbole in JavaScript brauchen?
private
undpublic
Klassenattribut Schlüsselwort , dass sie beschlossen , für eine einfachere Implementierung Klasse zu Graben. Anstelle vonthis.x = x
dir solltepublic x = x
und für private Variablenprivate y = y
. Sie beschlossen, dies für eine wesentlich minimalere Klassenimplementierung aufzugeben. Das Symbol wäre dann eine erforderliche Problemumgehung, um private Eigenschaften in der minimalen Implementierung zu erhalten.Antworten:
Die ursprüngliche Motivation für die Einführung von Symbolen in Javascript bestand darin, private Immobilien zu ermöglichen .
Leider wurden sie stark herabgestuft. Sie sind nicht mehr privat, da Sie sie beispielsweise durch Reflektion finden können
Object.getOwnPropertySymbols
oder Proxys finden können.Sie sind jetzt als einzigartig bekannt Symbole bezeichnet und dienen nur dazu, Namenskonflikte zwischen Eigenschaften zu vermeiden. Beispielsweise kann ECMAScript selbst jetzt Erweiterungs-Hooks über bestimmte Methoden einführen, die Sie Objekten zuweisen können (z. B. um deren Iterationsprotokoll zu definieren), ohne dass das Risiko besteht, dass sie mit Benutzernamen in Konflikt geraten.
Ob dies stark genug ist, um der Sprache Symbole hinzuzufügen, ist umstritten.
quelle
Object.getOwnPropertySymbols
nicht das einzige Leck; Schwieriger ist die Möglichkeit, mithilfe von Proxys den Zugriff auf eine "private" Eigenschaft abzufangen.Symbole garantieren keine echte Privatsphäre, können jedoch verwendet werden, um öffentliche und interne Eigenschaften von Objekten zu trennen. Nehmen wir ein Beispiel, in dem wir
Symbol
private Immobilien haben können.Nehmen wir ein Beispiel, in dem eine Eigenschaft eines Objekts nicht privat ist.
Oben ist die
Pet
Klasseneigenschafttype
nicht privat. Um es privat zu machen, müssen wir einen Verschluss erstellen. Das folgende Beispiel zeigt, wie wirtype
mit einem Verschluss privat machen können .Nachteil des obigen Ansatzes: Wir führen für jede
Pet
erstellte Instanz einen zusätzlichen Abschluss ein , der die Leistung beeinträchtigen kann.Jetzt stellen wir vor
Symbol
. Dies kann uns helfen, eine Immobilie privat zu machen, ohne zusätzliche unnötige Schließungen zu verwenden. Codebeispiel unten:quelle
_
keine echte Privatsphäre garantiert, sondern dazu verwendet werden kann, öffentliche und interne Eigenschaften von Objekten zu trennen. Mit anderen Worten, sinnlose Antwort.Symbols
sind eine neue, spezielle Art von Objekt, das als eindeutiger Eigenschaftsname in Objekten verwendet werden kann. Durch die Verwendung vonSymbol
anstelle vonstring
's können verschiedene Module Eigenschaften erstellen, die nicht miteinander in Konflikt stehen.Symbols
kann auch privat gemacht werden, so dass niemand auf seine Eigenschaften zugreifen kann, der noch keinen direkten Zugriff auf die hatSymbol
.Symbols
sind ein neues Primitiv . Genau wie dienumber
,string
undboolean
PrimitivenSymbol
haben sie eine Funktion, mit der sie erstellt werden können.Symbols
Haben Sie im Gegensatz zu den anderen Grundelementen keine wörtliche Syntax (z. B. wiestring
haben''
) - die einzige Möglichkeit, sie zu erstellen, besteht darin, denSymbol
Konstruktor folgendermaßen zu verwenden:In Wirklichkeit ist
Symbol
es nur eine etwas andere Art, Eigenschaften an ein Objekt anzuhängen - Sie könnten leicht die bekanntenSymbols
Standardmethoden bereitstellen , wie sieObject.prototype.hasOwnProperty
in allem, was von ihnen erbt, vorkommenObject
.Hier sind einige der Vorteile des
Symbol
primitiven Typs.Symbols
Debuggabilität eingebaut habenSymbols
kann eine Beschreibung gegeben werden, die wirklich nur zum Debuggen verwendet wird, um das Leben ein wenig einfacher zu machen, wenn sie an einer Konsole protokolliert werden.Symbols
kann alsObject
Schlüssel verwendet werdenHier wird
Symbol
es wirklich interessant. Sie sind stark mit Objekten verflochten.Symbol
kann als Schlüssel für Objekte zugewiesen werden, dh Sie könnenSymbol
einem Objekt eine unbegrenzte Anzahl von eindeutigen Elementen zuweisen und sicherstellen, dass diese niemals mitstring
Schlüsseln oder anderen eindeutigen Schlüsseln in Konflikt stehenSymbols
.Symbols
kann als eindeutiger Wert verwendet werden.Nehmen wir an , Sie eine Logging - Bibliothek, die mehrere Protokollebenen wie beinhaltet
logger.levels.DEBUG
,logger.levels.INFO
,logger.levels.WARN
und so weiter. Im ES5-Code möchten Sie diesestring
s (sologger.levels.DEBUG === 'debug'
) odernumber
s (logger.levels.DEBUG === 10
) erstellen . Beide sind nicht ideal, da diese Werte keine eindeutigen Werte sind, aberSymbol
s! So wirdlogger.levels
einfach:Lesen Sie mehr in diesem großartigen Artikel .
quelle
log.levels = {DEBUG: Symbol('debug')
und nicht einfachlog.levels = {DEBUG:'debug'}
. am Ende ist es das gleiche. Ich denke, es ist erwähnenswert, dass Symbole unsichtbar sind, wenn über die Schlüssel eines Objekts iteriert wird. das ist ihr "Ding"{}
dasselbe Ergebnis verwenden und erzielen kann (als eindeutiger Wert) oder vielleicht ein Literal in diesem Projekt bevorzugt wird, oder man kann sagen, dass man zuerst das Dokument lesen muss.) I. Ich persönlich denke, es bietet eine gute Lesbarkeit von einzigartiger Bedeutung im CodeSymbol("some message")
wird{message:'some message'}
, wohl Objekt tut besser hier , wie Sie mehr Feld hinzufügen können.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:
Oder so:
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önntenconsole.log
(was fair ist, da der Wert für das Debuggen ist, um dieses Protokoll nicht mit einem anderen Protokolleintrag zu verwechseln):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.
Nennen wir diese Symbole "Symbole vom zweiten Typ". Sie überschneiden sich nicht mit den Symbolen des "ersten Typs" (dh denjenigen, die mit definiert sind
Symbol(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.
Was ist, wenn wir zwei Personen mit dem Namen Peter haben?
Dies tun:
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".Jetzt haben wir zwei verschiedene Personen mit dem gleichen Namen. Sind unsere Personen wirklich anders? Sie sind; Sie können dies überprüfen:
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.
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.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:Welchen Unterschied
Symbol()
bringt es dort? Der Unterschied besteht darin, dass Sie die Eigenschaft weiterhinObject.defineProperty
auf die übliche Weise definieren können:Und wenn mit Symbol wie im vorherigen Absatz definiert:
Sie können den Wert nur erhalten, wenn Sie die Variable kennen, d. H.
"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üsselSymbol()
, 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.
quelle
So sehe ich das. Symbole bieten ein zusätzliches Maß an Datenschutz, indem sie verhindern, dass die Schlüssel / Eigenschaften eines Objekts durch einige gängige Methoden wie Object.keys () und JSON.stringify () verfügbar gemacht werden.
Obwohl ein Objekt an sich gegeben ist, können solche Eigenschaften dennoch durch Reflection, Proxy, Object.getOwnPropertySymbols () usw. verfügbar gemacht werden. Es gibt jedoch keine natürlichen Mittel, um über einige direkte Methoden auf sie zuzugreifen, was manchmal aus OOP-Sicht ausreichend sein kann.
quelle
Ein JS-Symbol ist ein neuer primitiver Datentyp. Dies sind Token, die als eindeutige IDs dienen . Mit dem
Symbol
Konstruktor kann ein Symbol erstellt werden . Nehmen Sie zum Beispiel diesen Ausschnitt aus MDN:Es ist oft praktisch, Symbole als eindeutige Objekteigenschaftsschlüssel zu verwenden, zum Beispiel:
quelle
Quelle
quelle