W3docs

Il tipo Symbol in JavaScript

Scopri il tipo Symbol in JavaScript: creare valori unici, usarli come chiavi nascoste, il registro globale con Symbol.for e Symbol.keyFor, e i simboli ben noti come Symbol.iterator e Symbol.toPrimitive.

Introduzione ai Symbol in JavaScript

I Symbol, introdotti in ECMAScript 2015 (ES6), sono un tipo di dato unico e immutabile usato principalmente per aggiungere chiavi di proprietà univoche agli object. Questa guida esplora i Symbol, le loro applicazioni pratiche e il modo in cui arricchiscono lo sviluppo JavaScript grazie a identificatori unici e capacità di meta-programmazione.

Comprendere i Symbol

Un Symbol è un valore primitivo unico e immutabile che può essere utilizzato come chiave di una proprietà di un object. Ogni valore Symbol restituito da Symbol() è distinto da tutti gli altri, garantendone l'unicità.

Esempio: creare e usare i Symbol

javascript— editable

sym1 viene creato senza descrizione, mentre sym2 e sym3 vengono creati con la stessa descrizione. Nonostante abbiano la stessa descrizione, sym2 e sym3 sono Symbol distinti.

Si noti che in questo esempio la funzione String() viene utilizzata per convertire i Symbol in formato string per un logging sicuro.

I Symbol come chiavi di proprietà

Usare i Symbol come chiavi di proprietà consente di aggiungere proprietà "nascoste" che la normale enumerazione ignora. Una proprietà con chiave symbol viene ignorata da for...in, da Object.keys() e da JSON.stringify(). Questo è ciò che rende i Symbol utili per memorizzare metadati che non devono trapelare nell'output serializzato o nei loop accidentali. Per recuperare le chiavi symbol si utilizzano Object.getOwnPropertySymbols() o Reflect.ownKeys() (quest'ultimo restituisce sia le chiavi string sia quelle symbol). È comunque possibile controllare gli attributi della proprietà symbol — writable, enumerable, configurable — tramite Object.defineProperty(), esattamente come si farebbe con una chiave string (vedi Flag e descrittori di proprietà).

Per usare un Symbol come chiave in un object literal, racchiuderlo tra parentesi quadre: [id]. Senza le parentesi, il literal creerebbe una chiave string ordinaria chiamata "id".

Esempio: i Symbol vengono ignorati dall'enumerazione

javascript— editable

L'object user memorizza 123 sotto una chiave symbol leggibile solo se si possiede il Symbol originale id. Poiché Object.keys, for...in e JSON.stringify la ignorano, il valore non compare nei payload serializzati né nei loop generici sulle proprietà — ma non è davvero privato: chiunque abbia accesso a Object.getOwnPropertySymbols può comunque scoprirlo.

Condividere Symbol con Symbol.for e Symbol.keyFor

I Symbol creati con Symbol.for vengono salvati nel registro globale dei symbol e sono accessibili ovunque nel codice, garantendo riferimenti coerenti tramite i metodi Symbol.for e Symbol.keyFor.

Esempio: condividere Symbol

javascript— editable

La differenza fondamentale rispetto a Symbol(): Symbol.for(key) mantiene una tabella globale e cross-realm indicizzata per string. Chiamarla due volte con la stessa chiave restituisce lo stesso Symbol, anche da file o moduli diversi — utile quando parti indipendenti di un'applicazione devono concordare su un unico Symbol senza doverlo importare l'una dall'altra. Symbol.keyFor esegue la ricerca inversa, ma solo per i Symbol del registro; per un Symbol() ordinario restituisce undefined.

Utilizzo nel mondo reale

Di seguito alcuni esempi pratici di come i Symbol possono essere usati in scenari reali:

1. Gestione dell'accesso alle proprietà di un object

I Symbol sono particolarmente utili quando si vuole controllare l'accesso a certe proprietà di un object, assicurando che non vengano accidentalmente modificate o accedute tramite i metodi comuni di accesso alle proprietà.

Esempio: membri privati nelle classi

Quando si creano classi in JavaScript, può essere utile avere proprietà private che non devono essere accedute direttamente al di fuori dei metodi della classe. I Symbol offrono un modo per ottenere una forma di privacy.

javascript— editable

2. Evitare collisioni di proprietà

Quando si lavora con mixin o si estendono object di cui non si controllano tutti i nomi delle proprietà, i Symbol aiutano a evitare collisioni tra i nomi delle proprietà.

Esempio: mixin sicuri

Se si estende un object con funzionalità aggiuntive provenienti da più fonti, i Symbol garantiscono che non vi siano collisioni di chiavi che potrebbero sovrascrivere proprietà esistenti.

javascript— editable

3. Meta-programmazione

I Symbol sono fondamentali per le capacità di meta-programmazione di JavaScript. Alcuni symbol ben noti vengono usati per modificare o personalizzare il comportamento delle istanze di object. Oltre a Symbol.iterator, altri come Symbol.toStringTag (personalizza l'output di Object.prototype.toString) e Symbol.hasInstance (personalizza il comportamento di instanceof) offrono una profonda integrazione con il linguaggio.

Esempio: iteratori personalizzati

È possibile usare i Symbol per definire un comportamento di iterazione personalizzato sugli object tramite la proprietà Symbol.iterator.

javascript— editable

4. Symbol per il debugging

I Symbol possono essere utili anche a scopo di debugging, poiché consentono di allegare meta-informazioni agli object senza influenzarne il comportamento operativo.

Esempio: aggiungere informazioni di debug

javascript— editable

Questi esempi illustrano come i Symbol possano essere sfruttati in scenari pratici per gestire le proprietà degli object in modo più sicuro, estendere le funzionalità senza interferenze e facilitare tecniche di programmazione avanzate in JavaScript.

Symbol ben noti

JavaScript predefinisce un insieme di symbol "ben noti" sull'object Symbol stesso — ad esempio Symbol.iterator, Symbol.toPrimitive, Symbol.toStringTag e Symbol.hasInstance. Questi non si trovano nel registro globale; sono hook fissi che il linguaggio consulta in momenti specifici. Implementarne uno sul proprio object consente di personalizzare il comportamento built-in.

Personalizzare la conversione primitiva con Symbol.toPrimitive

Quando un object viene usato dove è atteso un primitivo — interpolazione di string, aritmetica, confronto — JavaScript chiama il metodo Symbol.toPrimitive dell'object (se presente), passando un hint pari a "string", "number" o "default". Questo offre un unico punto di controllo per ogni coercizione, invece di sovrascrivere separatamente toString e valueOf. Per l'insieme completo delle regole, vedi Conversione da object a primitivo.

javascript— editable

Poiché la logica di conversione risiede dietro una chiave symbol, non può mai collidere con le proprie proprietà dati e non compare mai in JSON.stringify.

Conclusione

I Symbol in JavaScript offrono un modo robusto per gestire identificatori unici e consentono agli sviluppatori di controllare le proprietà degli object con un alto grado di controllo e privacy. Utilizzando i Symbol, è possibile garantire che le proprietà vengano gestite in modo appropriato, evitando effetti collaterali indesiderati.

Esercizio

Pratica
Quali sono alcune caratteristiche del tipo Symbol in JavaScript?
Quali sono alcune caratteristiche del tipo Symbol in JavaScript?
Was this page helpful?