Un elemento simbolico rappresenta un valore univoco che non entra mai in conflitto con nessun altro valore, incluso il valore di altri elementi simbolici. Due stringhe primitive composte da caratteri identici vengono valutate come strettamente uguali:
String() === String()
> true
String( "My string." ) === String( "My string." );
> true
Tuttavia, nessun simbolo creato utilizzando la funzione Symbol()
può essere
sempre uguale:
Symbol() === Symbol()
> false
Questo trait ti consente di utilizzare i simboli come chiavi di proprietà univoche in un oggetto, evitando collisioni con le chiavi che qualsiasi altro codice potrebbe aggiungere all'oggetto.
const mySymbol = Symbol( "Desc" );
const myObject = {};
myObject[mySymbol] = "propSymbol";
myObject
> Object { Symbol("Desc"): "propSymbol" }
Esistono tre tipi di simboli:
- Simboli creati con
Symbol()
- Simboli condivisi impostati e recuperati da un registry di simboli globale utilizzando
Symbol.for()
- "Simboli noti" definiti come proprietà statiche nell'oggetto Symbol. Questi simboli contengono metodi interni che non possono essere sovrascritti accidentalmente.
Symbol()
accetta una descrizione (o "nome del simbolo") come argomento facoltativo.
Queste descrizioni sono etichette leggibili per scopi di debug e non influiscono sull'unicità del risultato. Qualsiasi chiamata a Symbol
restituisce una primitiva simbolo completamente univoca, anche se più chiamate hanno descrizioni identiche:
Symbol( "My symbol." ) === Symbol( "My symbol." );
> false
Come per altri tipi di dati primitivi, i simboli ereditano metodi e proprietà dal loro prototipo. Ad esempio, puoi accedere a una descrizione come proprietà ereditata del simbolo creato:
let mySymbol = Symbol( "My symbol." );
mySymbol.description
> "My symbol."
Tuttavia, non puoi creare un simbolo utilizzando la parola chiave new
:
let mySymbol = new Symbol();
> Uncaught TypeError: Symbol is not a constructor
I simboli non sono enumerabili, il che significa che le proprietà simboliche non sono disponibili
quando si utilizzano metodi standard per eseguirne l'iterazione. Il metodo getOwnPropertySymbols()
consente di accedere alle proprietà del simbolo di un oggetto.
Simboli condivisi
Il metodo Symbol.for()
tenta di cercare eventuali simboli esistenti in un
registro di simboli globale a livello di runtime con una determinata stringa come chiave e restituisce
il simbolo corrispondente se ne viene trovato uno. Se non ne trova uno, crea un simbolo con la chiave specificata e lo aggiunge al registry globale:
let sharedSymbol = Symbol.for( "My key." );
sharedSymbol === Symbol.for( "My key." )
> true
Queste chiavi non presentano sovrapposizioni funzionali con le descrizioni assegnate alle primitive Symbol
create dall'autore. Per accedere a un simbolo nel registry dei simboli,
devi prima crearlo utilizzando for()
:
Symbol( "String" ) === Symbol( "String" );
> false
Symbol( "String" ) === Symbol.for( "String" );
> false
Symbol.for( "String" ) === Symbol.for( "String" );
> true
Per recuperare la chiave di qualsiasi simbolo dal registry dei simboli, utilizza
Symbol.keyFor()
:
let mySymbol = Symbol.for( "Key." );
Symbol.keyFor( mySymbol ) ;
> "Key."
Simboli "noti"
I simboli noti sono proprietà statiche dell'oggetto Symbol
, ognuna delle quali è un simbolo. I simboli noti forniscono chiavi di proprietà univoche per accedere e modificare i metodi integrati di JavaScript, impedendo al contempo la sovrascrittura involontaria del comportamento di base.
Symbol;
> function Symbol()
asyncIterator: Symbol(Symbol.asyncIterator)
for: function for()
hasInstance: Symbol("Symbol.hasInstance")
isConcatSpreadable: Symbol("Symbol.isConcatSpreadable")
iterator: Symbol(Symbol.iterator)
keyFor: function keyFor()
length: 0
match: Symbol("Symbol.match")
matchAll: Symbol("Symbol.matchAll")
name: "Symbol"
prototype: Object { … }
replace: Symbol("Symbol.replace")
search: Symbol("Symbol.search")
species: Symbol("Symbol.species")
split: Symbol("Symbol.split")
toPrimitive: Symbol("Symbol.toPrimitive")
toStringTag: Symbol("Symbol.toStringTag")
unscopables: Symbol("Symbol.unscopables")
<prototype>: function ()
Poiché i simboli sono una funzionalità specifica di ES6, questi valori simbolici sono destinati a essere utilizzati come "punti di estensione" per gli sviluppatori che modificano il comportamento di JavaScript senza introdurre problemi di compatibilità con le versioni precedenti.
I valori dei simboli noti sono spesso stilizzati con un
prefisso @@
o racchiusi in %
per
differenziare le chiavi dai loro prototipi mutabili. Ad esempio, @@match
(o %match%
) è un riferimento all'immutabile Symbol.match
, non a
String.prototype.match
.
Verificare di aver compreso
Puoi utilizzare new
per creare un simbolo?
Quali dei seguenti descrivono simboli "noti"?