Questo post parla di Symbol()
, fornito con esempi reali che ho potuto trovare / creare e fatti e definizioni che ho trovato.
TLDR;
Il Symbol()
è il tipo di dati, introdotto con il rilascio di ECMAScript 6 (ES6).
Ci sono due fatti curiosi sul Simbolo.
il primo tipo di dati e il solo tipo di dati in JavaScript che non ha valore letterale
qualsiasi variabile, definita con Symbol()
, ottiene un contenuto unico, ma non è proprio privata .
tutti i dati ha il proprio simbolo, e per gli stessi dati Simboli sarebbe lo stesso . Maggiori informazioni nel paragrafo seguente, altrimenti non è un TLRD; :)
Come posso inizializzare il simbolo?
1. Per ottenere un identificatore univoco con un valore debuggable
Puoi farlo in questo modo:
var mySymbol1 = Symbol();
O in questo modo:
var mySymbol2 = Symbol("some text here");
La "some text here"
stringa non può essere estratta dal simbolo, è solo una descrizione a scopo di debug. Non cambia in alcun modo il comportamento del simbolo. Tuttavia, potresti console.log
farlo (il che è giusto, poiché il valore è per il debug, in modo da non confondere quel registro con un'altra voce di registro):
console.log(mySymbol2);
// Symbol(some text here)
2. Per ottenere un simbolo per alcuni dati di stringa
In questo caso il valore del simbolo viene effettivamente preso in considerazione e in questo modo due simboli potrebbero non essere univoci.
var a1 = Symbol.for("test");
var a2 = Symbol.for("test");
console.log(a1 == a2); //true!
Chiamiamo quei simboli simboli di "secondo tipo". Non si intersecano Symbol(data)
in alcun modo con i simboli di "primo tipo" (cioè quelli definiti con ).
I successivi due paragrafi riguardano solo il simbolo di primo tipo .
Come posso beneficiare dell'utilizzo di Symbol anziché dei tipi di dati precedenti?
Consideriamo innanzitutto un oggetto, un tipo di dati standard. Potremmo definire alcune coppie chiave-valori lì e avere accesso ai valori specificando la chiave.
var persons = {"peter":"pan","jon":"doe"};
console.log(persons.peter);
// pan
E se avessimo due persone con il nome di Peter?
Facendo questo:
var persons = {"peter":"first", "peter":"pan"};
non avrebbe molto senso.
Quindi, sembra essere un problema di due persone assolutamente diverse con lo stesso nome. Facciamo quindi riferimento nuovo Symbol()
. È come una persona nella vita reale - ogni persona è unica , ma i loro nomi possono essere uguali. Definiamo due "persone".
var a = Symbol("peter");
var b = Symbol("peter");
Ora abbiamo due persone diverse con lo stesso nome. Le nostre persone sono davvero diverse? Loro sono; puoi controllare questo:
console.log(a == b);
// false
Come possiamo trarne vantaggio?
Possiamo inserire due voci nel tuo oggetto per le diverse persone e non possono essere confuse in alcun modo.
var firstPerson = Symbol("peter");
var secondPerson = Symbol("peter");
var persons = {[firstPerson]:"first", [secondPerson]:"pan"};
Nota:
vale la pena notare, tuttavia, che stringendo l'oggetto con JSON.stringify
verranno eliminate tutte le coppie inizializzate con un simbolo come chiave.
L'esecuzione Object.keys
non restituirà tali Symbol()->value
coppie.
Usando questa inizializzazione, è assolutamente impossibile confondere le voci per la prima e la seconda persona. Chiamandoli console.log
verranno emessi correttamente i loro secondi nomi.
console.log(persons[a]);
// first
console.log(persons[b]);
// pan
Se utilizzato nell'oggetto, in che modo è diverso rispetto alla definizione di proprietà non enumerabile?
In effetti, esisteva già un modo per definire una proprietà da nascondere Object.keys
ed enumerare. Ecco qui:
var anObject = {};
var fruit = "apple";
Object.defineProperty( anObject, fruit, {
enumerable: false,
value: "green"
});
Che differenza ci Symbol()
porta lì? La differenza è che puoi ancora ottenere la proprietà definita con Object.defineProperty
nel solito modo:
console.log(anObject[fruit]); //green
console.log(anObject["apple"]); //green
console.log(anObject.apple); //green
E se definito con Symbol come nel paragrafo precedente:
fruit = Symbol("apple");
Avrai la possibilità di ricevere il suo valore solo se conoscendo la sua variabile, cioè
console.log(anObject[fruit]); //green
console.log(anObject["apple"]); //undefined
console.log(anObject.apple); //undefined
Inoltre, la definizione di un'altra proprietà sotto la chiave "apple"
farà cadere l'oggetto più vecchio (e se codificato, potrebbe generare un errore). Quindi niente più mele! È un peccato. Facendo riferimento al paragrafo precedente, i simboli sono unici e definiscono una chiave in quanto Symbol()
la renderà unica.
Digitare la conversione e il controllo
A differenza di altri tipi di dati, è impossibile convertirli Symbol()
in qualsiasi altro tipo di dati.
È possibile "rendere" un simbolo basato sul tipo di dati primitivo chiamando Symbol(data)
.
In termini di controllo del tipo, non cambia nulla.
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