Con le specifiche di ECMAScript 2015 è stato introdotto un nuovo tipo di dato primitivo a fianco ai sei tradizionali: il tipo di dato Symbol. A differenza però dei tipi di dato tradizionali, i simboli non prevedono una sintassi letterale. Cioè, mentre ad esempio possiamo identificare le stringhe come sequenze di caratteri tra apici o doppi apici, i booleani come i valori true
e false
, ect. per i simboli non abbiamo questa possibilità. L'unico modo per creare un simbolo è la funzione Symbol(), come mostrato nel seguente esempio:
var x = Symbol();
Anche se provassimo a scrivere sulla console il valore della variabile x
non otterremmo un valore esplicito ma il nome della funzione Symbol():
console.log(x); //risultato: Symbol()
Mentre se proviamo ad individuare il tipo di dati della variabile x otterremo il valore symbol:
console.log(typeof x); //risultato: symbol
Questo tipo di dato un po' misterioso ha alcune caratteristiche altrettanto misteriose. Ogni volta che generiamo un simbolo tramite la funzione Symbol(), JavaScript crea un valore univoco. Anche se non abbiamo un accesso diretto al valore generato, possiamo verificare l'univocità del valore nel seguente modo:
console.log(Symbol() === Symbol()); //risultato: false
Il confronto tra i due simboli generati restituisce sempre il valore false
, ad indicarci che non possiamo creare due simboli identici.
In fase di creazione possiamo assegnare una descrizione al simbolo generato:
var x = Symbol("mioSimbolo");
Ma questo non vuol dire che due simboli con la stessa descrizione abbiano lo stesso valore:
console.log(Symbol("mioSimbolo") === Symbol("mioSimbolo")); // risultato: false
L'assegnamento di una descrizione ad un simbolo serve per poter riconoscere in qualche modo il valore di un simbolo, come nel seguente esempio:
var x = Symbol("mioSimbolo");
console.log(x.toString() === "Symbol(mioSimbolo)"); //risultato: true
Il metodo for()
Ma questo non è un approccio affidabile, per quanto abbiamo visto prima a proposito dell'assegnamento di una descrizione ad un simbolo. Un modo per ottenere simboli riutilizzabili, cioè richiamabili con una descrizione consiste nell'utilizzare il metodo for(), come mostrato di seguito:
var x = Symbol.for("mioSimbolo");
Questo assegnamento crea un nuovo simbolo associato alla descrizione mioSimbolo
e lo assegna alla variabile x
. A differenza dell'approccio visto prima, però, se un simbolo associato alla descrizione mioSimbolo
era già stato creato tramite for()
, allora viene recuperato tale valore ed assegnato alla variabile.
Questo ci consente dunque di avere una corrispondenza tra descrizione e simbolo e di confrontare simboli come nell'esempio seguente:
var x = Symbol.for("mioSimbolo");
var y = Symbol.for("mioSimbolo");
console.log(x === y); // risultato: true
Un aspetto a cui bisogna stare attenti quando si utilizza il metodo for()
è che stiamo creando un simbolo con visibilità globale a livello di runtime. Questo vuol dire che il simbolo generato sarà accessibile non solo da qualsiasi parte di un'applicazione JavaScript, ma anche tra contesti diversi come ad esempio da un iframe
definito all'interno di una pagina Web.
Possiamo effettuare l'operazione inversa al for(), cioè recuperare la descrizione di un simbolo, utilizzando il metodo keyFor(), come vediamo di seguito:
var x = Symbol.for("mioSimbolo");
console.log(Symbol.keyFor(x)); //risultato: mioSimbolo