You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 1-js/04-object-basics/08-symbol/article.md
+50-59Lines changed: 50 additions & 59 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,29 +1,29 @@
1
1
2
2
# Il tipo Symbol
3
3
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.
5
5
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.
7
7
8
8
## Symbol
9
9
10
-
Il valore "Symbol" rappresenta un identificatore unico.
10
+
Il valore "Symbol" rappresenta un identificatore univoco.
11
11
12
-
Un valore di questo tipo può essere creato `Symbol()`:
12
+
Un valore di questo tipo può essere creato usando `Symbol()`:
13
13
14
14
```js
15
15
// id è un nuovo symbol
16
16
let id =Symbol();
17
17
```
18
18
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:
20
20
21
21
```js
22
22
// id è un symbol con descrizione "id"
23
23
let id =Symbol("id");
24
24
```
25
25
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.
27
27
28
28
Ad esempio, qui abbiamo due simboli con la stessa descrizione -- ma non sono uguali:
29
29
@@ -36,10 +36,10 @@ alert(id1 == id2); // false
36
36
*/!*
37
37
```
38
38
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.
40
40
41
41
````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.
43
43
44
44
Ad esempio, questo `alert` vi mostrerà un errore:
45
45
@@ -49,25 +49,35 @@ let id = Symbol("id");
49
49
alert(id); // TypeError: Cannot convert a Symbol value to a string
50
50
*/!*
51
51
```
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
+
53
56
```js run
54
57
let id = Symbol("id");
55
58
*!*
56
59
alert(id.toString()); // Symbol(id), ora funziona
57
60
*/!*
58
61
```
59
62
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
+
```
61
71
````
62
72
63
73
## Proprietà "nascoste"
64
74
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.
66
76
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.
68
78
69
79
```js run
70
-
let user = { //belongs to another code
80
+
let user = { //appartiene ad un altro codice
71
81
name:"John"
72
82
};
73
83
@@ -80,9 +90,9 @@ alert( user[id] ); // possiamo accedere ai dati utilizzando il symbol come chiav
80
90
81
91
Qual'è il beneficio di utilizzare `Symbol("id")` piuttosto che `"id"`?
82
92
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.
84
94
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.
86
96
87
97
Quindi ogni script può creare il suo `Symbol("id")`:
88
98
@@ -95,7 +105,7 @@ user[id] = "Their id value";
95
105
96
106
Non ci saranno conflitti, poiché i simboli saranno sempre differenti, anche se hanno lo stesso nome.
97
107
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:
99
109
100
110
```js
101
111
let user = { name:"John" };
@@ -109,9 +119,9 @@ user.id = "Their id value"
109
119
// boom! sovrascritto! non intendeva danneggiare il codice del collega, ma lo ha fatto!
110
120
```
111
121
112
-
### Symbol negli oggetti letterali
122
+
### Symbol in un *object literal*
113
123
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.
115
125
116
126
Come nell'esempio:
117
127
@@ -142,16 +152,16 @@ let user = {
142
152
};
143
153
144
154
*!*
145
-
for (let key in user) alert(key); // name, age (no symbols)
155
+
for (let key in user) alert(key); // name, age (nessun symbol)
146
156
*/!*
147
157
148
158
// l'accesso diretto al symbol funziona
149
159
alert( "Direct: "+ user[id] );
150
160
```
151
161
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.
153
163
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:
155
165
156
166
```js run
157
167
let id =Symbol("id");
@@ -164,35 +174,17 @@ let clone = Object.assign({}, user);
164
174
alert( clone[id] ); // 123
165
175
```
166
176
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`).
184
178
185
179
## Symbol globali
186
180
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à.
190
182
191
183
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.
192
184
193
185
Per poter leggere (o creare in caso di assenza) un symbol nel registro va usata la sintassi `Symbol.for(key)`.
194
186
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`.
196
188
197
189
Ad esempio:
198
190
@@ -207,7 +199,7 @@ let idAgain = Symbol.for("id");
207
199
alert( id === idAgain ); // true
208
200
```
209
201
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.
211
203
212
204
```smart header="Assomigliano a Ruby"
213
205
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
222
214
Ad esempio:
223
215
224
216
```js run
225
-
//get symbol by name
217
+
//estraiamo symbol dal nome
226
218
let sym =Symbol.for("name");
227
219
let sym2 =Symbol.for("id");
228
220
229
-
//prende name da symbol
221
+
//estraiamo il nome dal symbol
230
222
alert( Symbol.keyFor(sym) ); // name
231
223
alert( Symbol.keyFor(sym2) ); // id
232
224
```
233
225
234
226
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`.
235
227
236
-
Questo significa che ogni symbol possiede una proprietà `description`.
228
+
Detto questo, ogni symbol possiede una proprietà `description`.
237
229
238
230
Ad esempio:
239
231
240
232
```js run
241
233
let globalSymbol =Symbol.for("name");
242
234
let localSymbol =Symbol("name");
243
235
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
246
238
247
239
alert( localSymbol.description ); // name
248
240
```
249
241
250
-
## Sistemi per symbol
242
+
## Symbol di sistema
251
243
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.
253
245
254
246
Questi sono elencati in dettaglio nella tabella [Well-known symbols](https://tc39.github.io/ecma262/#sec-well-known-symbols) :
255
247
@@ -261,23 +253,22 @@ Questi sono elencati in dettaglio nella tabella [Well-known symbols](https://tc3
261
253
262
254
Ad esempio, `Symbol.toPrimitive` ci consente di descrivere l'oggetto per la conversione ad un tipo primitivo. Vedremo meglio come utilizzarlo a breve.
263
255
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.
265
257
266
258
## Riepilogo
267
259
268
-
`Symbol` è un tipo primitivo per definire identificatori unici.
260
+
`Symbol` è un tipo primitivo per definire identificatori univoci.
269
261
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).
271
263
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.
273
265
274
266
I symbol hanno due principali ambiti d'uso:
275
267
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.
278
269
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.
280
271
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).
282
273
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