2015-11-22 11 views
15

Ich war schon immer mit Sprachen unterwegs und habe mit allem von C# über Lisp bis Scala bis Haskell gearbeitet, und in jeder Sprache, die sie unterstützte, haben sich die Symbole ziemlich ähnlich verhalten; Das heißt, zwei beliebige Symbole mit demselben Namen sind garantiert identisch, da sie Singleton-Objekte sind.Grundlegendes zu ES6-Symbolen

Racket: (equal? 'foo 'foo) wahre

Common Lisp: (eq 'foo 'foo) wahr

Rubin: :foo == :foo wahr

Scala: 'foo == 'foo wahr

ES6: Symbol('foo') === Symbol('foo')falsch

Der Vorteil, dass Symbole Singletons sind, liegt auf der Hand: Sie können sie in Maps/Dictionaries verwenden, ohne zu riskieren, dass Ihr Schlüssel nicht mit Ihren Eingaben übereinstimmt, weil die Sprache plötzlich anders entschieden hat (Ruby)

Warum also? dass ECMAScript 6 einen anderen Ansatz verfolgt und wie kann ich es umgehen?

Antwort

14

können Sie (Art-of) die Wirkung von Symbolen erhalten „Erkennbaren“ namentlich durch registriert mit (global) Symbole:

var s1 = Symbol.for("foo"); 
var s2 = Symbol.for("foo"); 
s1 === s2; // true 

Natürlich können Sie Ihre eigene Symbol Registrierung erstellen, mit einem Zuordnen einer Instanz oder eines einfachen Objekts.

bearbeiten — ich will hinzufügen, dass die Absicht der optionalen String-Parameter, wenn eine neue Symbol Instanz macht, ist eine Möglichkeit zu schaffen, den Sinn und Zweck eines Symbols den Programmierer identifizieren. Ohne diese Zeichenfolge funktioniert ein Symbol problemlos als Symbol. Wenn Sie jedoch ein Objekt in einem Debugger ausgeben, sind die Eigenschaften, die von solchen anonymen Symbolinstanzen eingegeben werden, nur Werte. Wenn Sie numerische Eigenschaften für ein Objekt mit Symbolschlüsseln beibehalten, werden nur einige Zahlen angezeigt, und das wäre verwirrend. Die mit einer Symbolinstanz verknüpfte Beschreibungszeichenfolge gibt dem Programmierer Referenzinformationen, ohne die Eindeutigkeit des Symbols als Schlüsselwert zu beeinträchtigen.

Schließlich können Sie immer das Ergebnis des Aufrufs .toString() auf zwei ähnlich konstruierten Symbol-Instanzen vergleichen. Ich verdächtigen, dass diese Praxis als fragwürdig betrachtet werden würde, aber Sie können es sicherlich tun.

bearbeiten mehr — es fällt mir ein, dass die Tatsache, dass die Standard Verhalten von Symbolerstellung in JavaScript um den Typ nützlicher macht als beispielsweise Atome in Erlang oder Schlüssel in Clojure. Da die Sprache standardmäßig einen Wert liefert, der garantiert eindeutig ist, wird das grundlegende Problem der Namespace-Kollision ziemlich gut gelöst. Es ist immer noch möglich, mit "bekannten" Symbolen zu arbeiten, aber es ist nett, einzigartige Werte zur Verfügung zu haben, ohne sich um Konflikte mit anderem Code kümmern zu müssen, der auch Kollisionen vermeiden könnte. JavaScript hat das etwas einzigartige und sicherlich einzigartig weit verbreitete und unkontrollierbare Problem eines globalen Namespace, der durch Code verunreinigt sein kann, den ein Programmierer nicht einmal kennt, weil Code in der Browserumgebung aufgrund der Aktionen einer anderen Partei kollidieren kann und einer beliebigen Anzahl von Softwarearchitekten unbekannt.

+1

Warum 'sort-of' scheint ein guter Weg zu sein, um es" zu umgehen " –

+0

@JaromandaX Nun, sie sind nicht in irgendeiner Weise beschränkt, aber ich denke, das ist der Fall für Symbole in einer anderen Sprache, die ich kenne (Erlang , Clojure, ... und das ist alles, woran ich gerade denken kann). – Pointy

+0

Diese Antwort bezieht sich nicht auf das "Warum". – Ben