Skip to content

Commit 5c1225c

Browse files
authored
Merge pull request #206 from pasor1/article/08-symbol
revisione - Symbol type
2 parents 022395e + b8bb966 commit 5c1225c

File tree

1 file changed

+50
-59
lines changed

1 file changed

+50
-59
lines changed

1-js/04-object-basics/08-symbol/article.md

Lines changed: 50 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
11

22
# Il tipo Symbol
33

4-
Secondo le specifiche, una proprietà di un oggetto può essere sia di tipo stringa che di tipo symbol("simbolo"). Non sono quindi accettati, numeri, valori booleani, solamente stringhe e symbol.
4+
Secondo le specifiche, le chiavi delle proprietà di un oggetto possono essere di tipo stringa o di tipo symbol("simbolo"). Non sono accettati numeri o valori booleani, solamente stringhe e symbol.
55

6-
Finora abbiamo visto solo stringhe. Ora proviamo a vedere i vantaggi forniti dal tipo symbol.
6+
Finora abbiamo utilizzato solo stringhe. Ora proviamo a vedere i vantaggi forniti dal tipo symbol.
77

88
## Symbol
99

10-
Il valore "Symbol" rappresenta un identificatore unico.
10+
Il valore "Symbol" rappresenta un identificatore univoco.
1111

12-
Un valore di questo tipo può essere creato `Symbol()`:
12+
Un valore di questo tipo può essere creato usando `Symbol()`:
1313

1414
```js
1515
// id è un nuovo symbol
1616
let id = Symbol();
1717
```
1818

19-
Possiamo fornire anche una descrizione al symbol (chiamata nome del symbol), utile per il debugging:
19+
Al momento della creazione, possiamo anche fornire una descrizione al symbol (chiamata nome del symbol), utile per il debugging:
2020

2121
```js
2222
// id è un symbol con descrizione "id"
2323
let id = Symbol("id");
2424
```
2525

26-
I Symbol garantiscono di essere unici. Anche se creiamo più simboli con la stessa descrizione, saranno comunque valori differenti. La descrizione è utile solamente come etichetta.
26+
I Symbol garantiscono di essere unici. Anche se creiamo più simboli con la stessa descrizione, saranno comunque valori differenti. La descrizione è utile solamente come etichetta, non ha effetto su nulla.
2727

2828
Ad esempio, qui abbiamo due simboli con la stessa descrizione -- ma non sono uguali:
2929

@@ -36,10 +36,10 @@ alert(id1 == id2); // false
3636
*/!*
3737
```
3838

39-
Se conoscete linguaggi come Ruby che utilizzano una keyword "symbol" fate attenzione. I symbol in JavaScript sono differenti.
39+
Se conosci Ruby, od altri linguaggi che possiedono la keyword "symbol", fai attenzione a non confonderti. I symbol in JavaScript sono differenti.
4040

4141
````warn header="I symbol non si auto-convertono a stringa"
42-
Molti valori in JavaScript supportano la conversione implicita a stinga. Ad esempio, possiamo utilizzare `alert` con quasi tutti i valori, e funzionerà ugualmente. Symbol è un tipo speciale. Infatti non verrà convertito.
42+
Molti valori in JavaScript supportano la conversione implicita a stinga. Ad esempio, possiamo utilizzare `alert` con quasi tutti i valori, e funzionerà ugualmente. Symbol è un tipo speciale, non verrà convertito.
4343
4444
Ad esempio, questo `alert` vi mostrerà un errore:
4545
@@ -49,25 +49,35 @@ let id = Symbol("id");
4949
alert(id); // TypeError: Cannot convert a Symbol value to a string
5050
*/!*
5151
```
52-
Se vogliamo veramente mostrare un symbol, dobbiamo utilizzare `.toString()`:
52+
Questo è un "controllo del linguaggio" per prevenire pasticci, perché le stringhe e i symbol sono fondamentalmente differenti e non dovrebbero essere accidentalmente convertiti gli uni negli altri.
53+
54+
Se vogliamo veramente mostrare un symbol, dobbiamo convertirlo esplicitamente utilizzando `.toString()`:
55+
5356
```js run
5457
let id = Symbol("id");
5558
*!*
5659
alert(id.toString()); // Symbol(id), ora funziona
5760
*/!*
5861
```
5962
60-
Questo blocco è un "controllo di linguaggio" contro gli errori accidentali, perché le stringhe e i symbol sono fondamentalmente differenti e spesso non dovrebbe essere necessario convertirli.
63+
Oppure usare la proprietà symbol.description per mostrare solo la descrizione:
64+
65+
```js run
66+
let id = Symbol("id");
67+
*!*
68+
alert(id.description); // id
69+
*/!*
70+
```
6171
````
6272

6373
## Proprietà "nascoste"
6474

65-
Symbol ci consente di creare delle proprietà "nascoste" dentro un oggetto, quindi nessun'altra parte del codice potrà accedervi o modificarle.
75+
Symbol ci consente di creare delle proprietà "nascoste" dentro un oggetto, che nessun'altra parte del codice potrà leggere o modificare.
6676

67-
Ad esempio, se vogliamo memorizzare un "identificativo" per l'oggetto `user`, possiamo utilizzare symbol:
77+
Ad esempio, se stiamo lavorando con l'oggetto `user`, che appartiene a un codice di terze parti, e vogliamo aggiungere identificatore.
6878

6979
```js run
70-
let user = { // belongs to another code
80+
let user = { // appartiene ad un altro codice
7181
name: "John"
7282
};
7383

@@ -80,9 +90,9 @@ alert( user[id] ); // possiamo accedere ai dati utilizzando il symbol come chiav
8090

8191
Qual'è il beneficio di utilizzare `Symbol("id")` piuttosto che `"id"`?
8292

83-
Cerchiamo di andare più in profondità per capirlo.
93+
Poiché l'oggetto `user` appartiene a un altro codice che lo utilizza, non dovremmo aggiungervi alcun campo, non è sicuro. Ma un *symbol* non è accessibile accidentalmente, il codice di terze parti probabilmente non lo vedrà nemmeno, quindi andrà tutto bene.
8494

85-
Immaginiamo che un altro script voglia avere una sua proprietà "id" dentro `user`. Questo potrebbe essere il caso di due librerie, quindi i due script sono ignari l'uno dell'altro.
95+
Inoltre, immagina che un altro script necessiti di avere il proprio identificatore all'interno di `user`. Potrebbe essere un'altra libreria JavaScript, e gli script sarebbero completamente inconsapevoli l'uno dell'altro.
8696

8797
Quindi ogni script può creare il suo `Symbol("id")`:
8898

@@ -95,7 +105,7 @@ user[id] = "Their id value";
95105

96106
Non ci saranno conflitti, poiché i simboli saranno sempre differenti, anche se hanno lo stesso nome.
97107

98-
Invece se proviamo ad utilizzare una stringa `"id"` piuttosto del symbol, *otterremo* un conflitto:
108+
Invece se proviamo ad utilizzare una stringa `"id"` piuttosto che symbol, otterremo un conflitto:
99109

100110
```js
101111
let user = { name: "John" };
@@ -109,9 +119,9 @@ user.id = "Their id value"
109119
// boom! sovrascritto! non intendeva danneggiare il codice del collega, ma lo ha fatto!
110120
```
111121

112-
### Symbol negli oggetti letterali
122+
### Symbol in un *object literal*
113123

114-
Se vogliamo utilizzare un symbol in un oggetto letterale, abbiamo bisogno delle parentesi quadre.
124+
Se vogliamo utilizzare un symbol in un *object literal* `{...}`, abbiamo bisogno di includerlo nelle parentesi quadre.
115125

116126
Come nell'esempio:
117127

@@ -142,16 +152,16 @@ let user = {
142152
};
143153

144154
*!*
145-
for (let key in user) alert(key); // name, age (no symbols)
155+
for (let key in user) alert(key); // name, age (nessun symbol)
146156
*/!*
147157

148158
// l'accesso diretto al symbol funziona
149159
alert( "Direct: " + user[id] );
150160
```
151161

152-
Anche `Object.keys(user)` li ignora. Questo è il meccanismo di occultazione delle proprietà symbol. Se uno script esterno o una libreria tenta di eseguire istruzioni sul nostro oggetto, non avrà la possibilità di accedere ad una proprietà di tipo symbol.
162+
Anche `Object.keys(user)` li ignora. Questo fa parte del principio generale di occultazione delle proprietà symbol. Se uno script esterno o una libreria eseguisse un ciclo sul nostro oggetto, non avrebbe inaspettatamente accesso a una proprietà di tipo symbol.
153163

154-
Invece [Object.assign](mdn:js/Object/assign) esegue la copia sia delle proprietà di tipo stringa si di quelle symbol:
164+
Invece [Object.assign](mdn:js/Object/assign) esegue la copia sia delle proprietà di tipo stringa sia di quelle symbol:
155165

156166
```js run
157167
let id = Symbol("id");
@@ -164,35 +174,17 @@ let clone = Object.assign({}, user);
164174
alert( clone[id] ); // 123
165175
```
166176

167-
Non c'è nulla di strano. E' una semplice scelta di design. L'idea è che quando vogliamo copiare o clonare un oggetto, solitamente abbiamo intenzione di copiarne *tutte* le proprietà (incluse quelle di tipo symbol come `id`).
168-
169-
````smart header="Le chiavi delle proprietà vengono convertite a stringhe"
170-
Possiamo utilizzare solamente stringhe o symbol come chiavi in un oggetto. Gli altri tipi vengono convertiti a stringa.
171-
172-
Ad esempio, un numero `0` diventa una stringa `"0"` quando lo utilizziamo come chiave di una proprietà:
173-
174-
```js run
175-
let obj = {
176-
0: "test" // equivale a "0": "test"
177-
};
178-
179-
// entrambi gli alert accedono alla stessa proprietà (il numero 0 è convertito a stringa "0")
180-
alert( obj["0"] ); // test
181-
alert( obj[0] ); // test (stessa proprietà)
182-
```
183-
````
177+
Non c'è nulla di strano. E' una semplice scelta di design. L'idea è che quando vogliamo clonare o unire oggetti, solitamente abbiamo intenzione di copiarne *tutte* le proprietà (incluse quelle di tipo symbol come `id`).
184178

185179
## Symbol globali
186180

187-
Come abbiamo visto solitamente i symbol sono differenti, persino quelli con gli stessi nomi. Qualche volta voglia che i symbol con nomi uguali vengano visti come una sola entità.
188-
189-
Ad esempio, parti differente del codice potrebbero voler accedere al symbol `"id"`, volendo utilizzare tutte la stessa proprietà.
181+
Come abbiamo visto, solitamente i symbol sono differenti, anche se hanno lo stesso nome. Ma a volte vogliamo che symbol con nomi uguali vengano visti come la stessa entità. Ad esempio, parti differenti del codice potrebbero voler accedere al symbol `"id"`, riferendosi alla stessa proprietà.
190182

191183
Per soddisfare questa necessità, esiste un *registro globale dei symbol*. Possiamo creare dei symbol al suo interno ed accedervi successivamente, e questo garantirà che lo stesso nome ritornerà esattamente lo stesso symbol.
192184

193185
Per poter leggere (o creare in caso di assenza) un symbol nel registro va usata la sintassi `Symbol.for(key)`.
194186

195-
Questa chiamata controlla il registro globale, se trova un symbol descritto dalla `key`, lo ritorna, altrimenti crea un nuovo simbolo `Symbol(key)` e lo memorizza nel registro con la chiave `key`.
187+
Questa chiamata controlla il registro globale, se trova un symbol descritto dalla `key`, lo ritorna, altrimenti crea un nuovo simbolo `Symbol(key)` e lo memorizza nel registro con la chiave `key`.
196188

197189
Ad esempio:
198190

@@ -207,7 +199,7 @@ let idAgain = Symbol.for("id");
207199
alert( id === idAgain ); // true
208200
```
209201

210-
I symbol dentro il registro vengono chiamati *symbol globali*. Se abbiamo bisogno di molti symbol, che siano accessibili ovunque nel codice -- questo è il modo.
202+
I symbols dentro il registro vengono chiamati *symbol globali*. Se abbiamo bisogno di molti symbol, che siano accessibili ovunque nel codice -- questo è il modo.
211203

212204
```smart header="Assomigliano a Ruby"
213205
In alcuni linguaggi di programmazione, come Ruby, c'è un solo symbol per nome.
@@ -222,34 +214,34 @@ Per i symbol globali, non esiste solo `Symbol.for(key)` per accedere ad un symbo
222214
Ad esempio:
223215

224216
```js run
225-
// get symbol by name
217+
// estraiamo symbol dal nome
226218
let sym = Symbol.for("name");
227219
let sym2 = Symbol.for("id");
228220

229-
// prende name da symbol
221+
// estraiamo il nome dal symbol
230222
alert( Symbol.keyFor(sym) ); // name
231223
alert( Symbol.keyFor(sym2) ); // id
232224
```
233225

234226
La funzione `Symbol.keyFor` internamente utilizza il registro globale dei symbol per cercare la chiave del symbol. Quindi non avrà alcun effetto per symbol non globali. Se gli viene passato un symbol non globale, non sarà in grado di trovarlo e ritornerà `undefined`.
235227

236-
Questo significa che ogni symbol possiede una proprietà `description`.
228+
Detto questo, ogni symbol possiede una proprietà `description`.
237229

238230
Ad esempio:
239231

240232
```js run
241233
let globalSymbol = Symbol.for("name");
242234
let localSymbol = Symbol("name");
243235

244-
alert( Symbol.keyFor(globalSymbol) ); // name, global symbol
245-
alert( Symbol.keyFor(localSymbol) ); // undefined, non global
236+
alert( Symbol.keyFor(globalSymbol) ); // name, symbol globale
237+
alert( Symbol.keyFor(localSymbol) ); // undefined, non globale
246238

247239
alert( localSymbol.description ); // name
248240
```
249241

250-
## Sistemi per symbol
242+
## Symbol di sistema
251243

252-
In JavaScript esistono diversi "sistemi" per symbol, e possiamo utilizzarli per gestire vari aspetti dei nostri oggetti.
244+
In JavaScript esistono diversi *symbol di sistema*, e possiamo utilizzarli per gestire vari aspetti dei nostri oggetti.
253245

254246
Questi sono elencati in dettaglio nella tabella [Well-known symbols](https://tc39.github.io/ecma262/#sec-well-known-symbols) :
255247

@@ -261,23 +253,22 @@ Questi sono elencati in dettaglio nella tabella [Well-known symbols](https://tc3
261253

262254
Ad esempio, `Symbol.toPrimitive` ci consente di descrivere l'oggetto per la conversione ad un tipo primitivo. Vedremo meglio come utilizzarlo a breve.
263255

264-
Altri simboli diventeranno più familiari man mano che studieremo il linguaggio.
256+
Altri symbol diventeranno più familiari quando studieremo le corrispondenti caratteristiche del linguaggio.
265257

266258
## Riepilogo
267259

268-
`Symbol` è un tipo primitivo per definire identificatori unici.
260+
`Symbol` è un tipo primitivo per definire identificatori univoci.
269261

270-
I symbol vengono creati con una chiamata a `Symbol()`, aggiungendo una descrizione opzionale.
262+
I symbol vengono creati con una chiamata a `Symbol()`, aggiungendo una descrizione opzionale (nome).
271263

272-
I symbol sono sempre differenti, anche se hanno lo stesso nome. Se abbiamo bisogno di avere symbol con lo stesso nome che uguali tra lo, dovremmo utilizzare il registro globale: `Symbol.for(key)` ritorna un symbol globale con la `key` (se non esiste la crea). Diverse chiamate di `Symbol.for` ritorneranno sempre lo stesso symbol.
264+
I symbol sono sempre differenti, anche se hanno lo stesso nome. Se abbiamo bisogno di avere symbol con lo stesso nome ed uguali tra loro, dovremmo utilizzare il registro globale: `Symbol.for(key)` ritorna un symbol globale con la `key` (se non esiste la crea). Diverse chiamate di `Symbol.for` ritorneranno sempre lo stesso symbol.
273265

274266
I symbol hanno due principali ambiti d'uso:
275267

276-
1. "Nascondere" le proprietà di un oggetto.
277-
Se vogliamo aggiungere una proprietà in un oggetto che "appartiene" ad un altro script (o libreria), possiamo creare un symbol ed utilizzarlo come chiave della proprietà. Una proprietà di tipo symbol non sarà disponibile in un `for..in`, quindi non sarà mai resa visibile. Non sarà nemmeno accessibile direttamente poiché uno script diverso non potrà avere i nostri symbol.
268+
1. "Nascondere" le proprietà di un oggetto. Se vogliamo aggiungere una proprietà ad un oggetto che "appartiene" ad un altro script (o libreria), possiamo creare un symbol ed utilizzarlo come chiave della proprietà. Una proprietà di tipo symbol non sarà disponibile in un `for..in`, quindi non sarà mai resa visibile. Non sarà nemmeno accessibile direttamente poiché uno script diverso non potrà avere i nostri symbol. Quindi la proprietà sarà protetta dall'uso accidentale o dalla sovrascrittura.
278269

279-
Possiamo quindi "nascondere" una proprietà di un oggetto se ne abbiamo al necessità, senza che nessun altro possa vederlo, usando proprietà di tipo symbol.
270+
Possiamo quindi aggiungere "di nascosto" una proprietà in un oggetto se ne abbiamo la necessità, senza che nessun altro possa vederla, usando proprietà di tipo symbol.
280271

281-
2. Ci sono diversi sistemi di symbol utilizzati da JavaScript che sono accessibili come `Symbol.*`. Possiamo utilizzarli per modificare alcune caratteristiche incorporate. Ad esempio, più avanti nella guida utilizzeremo `Symbol.iterator` per [iterables](info:iterable), `Symbol.toPrimitive` per impostare la [conversione da oggetto a primitivo](info:object-toprimitive).
272+
2. Ci sono diversi symbol di sistema utilizzati da JavaScript che sono accessibili come `Symbol.*`. Possiamo utilizzarli per modificare alcune caratteristiche native. Ad esempio, più avanti nella guida utilizzeremo `Symbol.iterator` per [iterables](info:iterable), `Symbol.toPrimitive` per impostare la [conversione da oggetto a primitivo](info:object-toprimitive).
282273

283-
Tecnicamente i symbol non sono nascosti al 100%. C'è un metodo integrato in JavaScript [Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) che ci consente di ottenere tutti i symbol. Esiste anche un metodo chiamato [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) che ritorna *tutte* le chiavi di un oggetto incluse quelle di tipo symbol. Quindi non sono realmente invisibili. Molte librerie ne fanno utilizzo, come accordo comune. Chi proverà esplicitamente ad utilizzarle probabilmente è abbastanza esperto da capire ciò che sta facendo.
274+
Tecnicamente i symbol non sono nascosti al 100%. C'è un metodo nativo in JavaScript [Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) che ci consente di ottenere tutti i symbol. Esiste anche un metodo chiamato [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) che ritorna *tutte* le chiavi di un oggetto incluse quelle di tipo symbol. Quindi non sono realmente invisibili. Ma la maggior parte delle librerie, delle funzioni native e dei costrutti non utilizzano questi metodi.

0 commit comments

Comments
 (0)