Skip to content

Commit 7dd6584

Browse files
authored
Merge pull request #187 from longo-andrea/article/optional-chaining
Optional chaining '?.'
2 parents 6bc49fb + 48a981a commit 7dd6584

File tree

1 file changed

+78
-78
lines changed
  • 1-js/04-object-basics/07-optional-chaining

1 file changed

+78
-78
lines changed
Lines changed: 78 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,98 @@
11

2-
# Optional chaining '?.'
2+
# Concatenamento opzionale '?.'
33

44
[recent browser="new"]
55

6-
The optional chaining `?.` is a safe way to access nested object properties, even if an intermediate property doesn't exist.
6+
Il concatenamento opzionale (optional chaining), `?.`, è un modo sicuro di accedere alle proprietà annidate di un oggetto, anche nel caso in cui una proprietà intermedia non dovesse esistere.
77

8-
## The "non-existing property" problem
8+
## Il problema della "proprietà inesistente"
99

10-
If you've just started to read the tutorial and learn JavaScript, maybe the problem hasn't touched you yet, but it's quite common.
10+
Se avete appena cominciato a leggere il tutorial e a imparare JavaScript, forse questo problema non lo avete ancora affrontato, ma è piuttosto comune.
1111

12-
As an example, let's say we have `user` objects that hold the information about our users.
12+
Ad esempio, ipotizziamo di avere un oggetto `user`, in cui sono memorizzate le informazioni relative ai nostri utenti.
1313

14-
Most of our users have addresses in `user.address` property, with the street `user.address.street`, but some did not provide them.
14+
La maggior parte dei nostri utenti possiedono l'indirizzo nella proprietà `user.address`, la via in `user.address.street`, ma qualcuno potrebbe non averle fornite.
1515

16-
In such case, when we attempt to get `user.address.street`, and the user happens to be without an address, we get an error:
16+
In questo caso, quando proviamo ad accedere a `user.address.street`, e l'utente non possiede un indirizzo, otterremo un errore:
1717

1818
```js run
19-
let user = {}; // a user without "address" property
19+
let user = {}; // un utente senza la proprietà "address"
2020

21-
alert(user.address.street); // Error!
21+
alert(user.address.street); // Errore!
2222
```
2323

24-
That's the expected result. JavaScript works like this. As `user.address` is `undefined`, an attempt to get `user.address.street` fails with an error.
24+
Questo è il risultato che ci si aspetta. JavaScript funziona in questo modo. Se `user.address` è `undefined`, un tentativo di accesso a `user.address.street` fallirà con un errore.
2525

26-
In many practical cases we'd prefer to get `undefined` instead of an error here (meaning "no street").
26+
Nella maggior parte dei casi, preferiremmo avere `undefined` piuttosto di un errore (con il significato "nessuna via").
2727

28-
...And another example. In the web development, we can get an object that corresponds to a web page element using a special method call, such as `document.querySelector('.elem')`, and it returns `null` when there's no such element.
28+
... Un altro esempio. Il metodo `document.querySelector('.elem')` ritorna un oggetto che corrisponde ad un elemento della pagina web, che ritorna `null` quando l'elemento non esite.
2929

3030
```js run
31-
// document.querySelector('.elem') is null if there's no element
32-
let html = document.querySelector('.elem').innerHTML; // error if it's null
31+
// document.querySelector('.elem') è null se non esiste l'elemento
32+
let html = document.querySelector('.elem').innerHTML; // errore se è null
3333
```
3434

35-
Once again, if the element doesn't exist, we'll get an error accessing `.innerHTML` of `null`. And in some cases, when the absence of the element is normal, we'd like to avoid the error and just accept `html = null` as the result.
35+
Di nuovo, se un elemente non esiste, otterremo un errore nel tentativo di accedere a `.innerHTML` di `null`. In alcuni casi, in cui l'assenza di un elemento è normale, vorremo evitare l'errore e accettare come risultato `html = null`.
3636

37-
How can we do this?
37+
Come possiamo farlo?
3838

39-
The obvious solution would be to check the value using `if` or the conditional operator `?`, before accessing its property, like this:
39+
La soluzione più ovvia sarebbe di controllare il valore utilizzando `if` o l'operatore condizionale `?`, prima di accedere alle proprietà, come nell'esempio:
4040

4141
```js
4242
let user = {};
4343

4444
alert(user.address ? user.address.street : undefined);
4545
```
4646

47-
It works, there's no error... But it's quite inelegant. As you can see, the `"user.address"` appears twice in the code. For more deeply nested properties, that becomes a problem as more repetitions are required.
47+
Funziona, nessun errore... Ma è poco elegante. Come potete vedere , `"user.address"` appare due volte nel codice. Per proprietà molto più annidate, potrebbe diventare un problema, in quanto saranno necessarie molte più ripetizioni.
4848

49-
E.g. let's try getting `user.address.street.name`.
49+
Ad esempio, proviamo a recuperare il valore di `user.address.street.name`.
5050

51-
We need to check both `user.address` and `user.address.street`:
51+
Dobbiamo verificare sia `user.address` che `user.address.street`:
5252

5353
```js
54-
let user = {}; // user has no address
54+
let user = {}; // l'utente non ha address
5555

5656
alert(user.address ? user.address.street ? user.address.street.name : null : null);
5757
```
5858

59-
That's just awful, one may even have problems understanding such code.
59+
Questo è semplicemente terribile, un codice del genere potrebbe essere difficile da comprendere.
6060

61-
Don't even care to, as there's a better way to write it, using the `&&` operator:
61+
Ci sarebbe un modo migliore per riscriverlo, utilizzando l'operatore `&&`:
6262

6363
```js run
64-
let user = {}; // user has no address
64+
let user = {}; // l'utente non ha address
6565

66-
alert( user.address && user.address.street && user.address.street.name ); // undefined (no error)
66+
alert( user.address && user.address.street && user.address.street.name ); // undefined (nessune errore)
6767
```
6868

69-
AND'ing the whole path to the property ensures that all components exist (if not, the evaluation stops), but also isn't ideal.
69+
Concatenare con `&&` l'intero percorso verso la proprietà ci assicura che tutti i componenti esistano (in caso contrario, la valutazione si interrompe), ma non è comunque l'ideale.
7070

71-
As you can see, property names are still duplicated in the code. E.g. in the code above, `user.address` appears three times.
71+
Come potete vedere, il nome della proprietà è ancora duplicato nel codice. Ad esempio, nel codice sopra, `user.address` è ripetuto tre volte.
7272

73-
That's why the optional chaining `?.` was added to the language. To solve this problem once and for all!
73+
Questo è il motivo per cui la concatenazione opzionale `?.` è stata aggiunta al linguaggio. Per risolvere questo problema una volta per tutte!
7474

75-
## Optional chaining
75+
## Concatenazione opzionale
7676

77-
The optional chaining `?.` stops the evaluation if the value before `?.` is `undefined` or `null` and returns `undefined`.
77+
La concatenazione opzionale `?.` interrompe la valutazione se il valore prima di `?.` è `undefined` o `null`, e ritorna `undefined`.
7878

79-
**Further in this article, for brevity, we'll be saying that something "exists" if it's not `null` and not `undefined`.**
79+
**D'ora in poi in questo articolo, per brevità, diremo che qualcosa "esiste" se non è ne `null` `undefined`.**
8080

81-
In other words, `value?.prop`:
82-
- works as `value.prop`, if `value` exists,
83-
- otherwise (when `value` is `undefined/null`) it returns `undefined`.
81+
In altre parole, `value?.prop`:
82+
- funziona come `value.prop`, se `value` esiste,
83+
- altrimenti (quando `value` è `undefined/null`) ritorna `undefined`.
8484

85-
Here's the safe way to access `user.address.street` using `?.`:
85+
Vediamo un modo sicuro per accedere a `user.address.street` utilizzando `?.`:
8686

8787
```js run
88-
let user = {}; // user has no address
88+
let user = {}; // user non possiede l'address
8989

90-
alert( user?.address?.street ); // undefined (no error)
90+
alert( user?.address?.street ); // undefined (nessun errore)
9191
```
9292
93-
The code is short and clean, there's no duplication at all.
93+
Il codice è corto e pulito, non c'è alcuna duplicazione.
9494
95-
Reading the address with `user?.address` works even if `user` object doesn't exist:
95+
Leggendo l'indirizzo con `user?.address` funzionerebbe anche se l'oggetto `user` non esistesse:
9696
9797
```js run
9898
let user = null;
@@ -101,52 +101,52 @@ alert( user?.address ); // undefined
101101
alert( user?.address.street ); // undefined
102102
```
103103
104-
Please note: the `?.` syntax makes optional the value before it, but not any further.
104+
Da notare: la sintassi `?.` rende opzionale il valore che la precede, nulla di più.
105105
106-
E.g. in `user?.address.street.name` the `?.` allows `user` to safely be `null/undefined` (and returns `undefined` in that case), but that's only for `user`. Further properties are accessed in a regular way. If we want some of them to be optional, then we'll need to replace more `.` with `?.`.
106+
Ad esempio in `user?.address.street.name` il costrutto `?.` permette alla proprietà `user` di essere `null/undefined` in sicurezza (e ritornare `undefined` in questo caso), ma questo vale solamente per `user`. Si accederà alle altre proprietà normalmente. Se vogliamo che anche altre proprietà siano opzionali, dobbiamo rimpiazzare `.` con `?.`.
107107
108-
```warn header="Don't overuse the optional chaining"
109-
We should use `?.` only where it's ok that something doesn't exist.
108+
```warn header="Non abusate della concatenazione opzionale"
109+
Dovremmo utilizzare `?.` solamente quando va bene che una proprietà possa non esistere.
110110

111-
For example, if according to our coding logic `user` object must exist, but `address` is optional, then we should write `user.address?.street`, but not `user?.address?.street`.
111+
Ad esempio, considerando la logica del nostro codice, l'oggetto `user` deve necessariamente esistere, mentre `address` è opzionale, quindi dovremmo scrivere `user.address?.street`, non `user?.address?.street`.
112112
113-
So, if `user` happens to be undefined due to a mistake, we'll see a programming error about it and fix it. Otherwise, coding errors can be silenced where not appropriate, and become more difficult to debug.
113+
Quindi, se `user` dovesse essere `undefined` per errore, otterremo un errore e potremmo sistemarlo. Altrimenti, gli errori di programmazione potrebbero essere silenziati in modo non appropriato, rendendo il debug molto difficile.
114114
```
115115
116-
````warn header="The variable before `?.` must be declared"
117-
If there's no variable `user` at all, then `user?.anything` triggers an error:
116+
````warn header="La variabile che precede `?.` deve essere dichiarata"
117+
Se non esiste alcuna variabile `user`, allora `user?.anything` provocherà un errore:
118118
119119
```js run
120120
// ReferenceError: user is not defined
121121
user?.address;
122122
```
123-
The variable must be declared (e.g. `let/const/var user` or as a function parameter). The optional chaining works only for declared variables.
123+
La variabile deve essere dichiarata (ad esempio come `let/const/var user` o come parametro di funzione). La concatenazione opzionale funziona solamente con le variabili dichiarate.
124124
````
125125
126-
## Short-circuiting
126+
## Corto circuito
127127
128-
As it was said before, the `?.` immediately stops ("short-circuits") the evaluation if the left part doesn't exist.
128+
Come detto in precedenza, il costrutto `?.` interrompe immediatamente (manda in "corto circuito") la valutazione se la proprietà a destra non esiste.
129129
130-
So, if there are any further function calls or side effects, they don't occur.
130+
Quindi, nel caso ci siano ulteriori chiamate a funzione o side-effects, questi non verranno elaborati.
131131
132-
For instance:
132+
Ad esempio:
133133
134134
```js run
135135
let user = null;
136136
let x = 0;
137137
138-
user?.sayHi(x++); // no "sayHi", so the execution doesn't reach x++
138+
user?.sayHi(x++); // non esiste "sayHi", quindi l'esecuzione non raggiungerà x++
139139

140-
alert(x); // 0, value not incremented
140+
alert(x); // 0, valore non incrementato
141141
```
142142
143-
## Other variants: ?.(), ?.[]
143+
## Altre varianti: ?.(), ?.[]
144144
145-
The optional chaining `?.` is not an operator, but a special syntax construct, that also works with functions and square brackets.
145+
La concatenazione opzionale `?.` non è un operatore, ma uno speciale costrutto sintattico, che funziona anche con le funzioni e le parentesi quadre.
146146
147-
For example, `?.()` is used to call a function that may not exist.
147+
Ad esempio, `?.()` viene utilizzato per invocare una funzione che potrebbe non esistere.
148148
149-
In the code below, some of our users have `admin` method, and some don't:
149+
Nel codice sotto, alcuni dei nostri utenti possiedono il metodo `admin`, mentre altri no:
150150
151151
```js run
152152
let userAdmin = {
@@ -162,15 +162,15 @@ userAdmin.admin?.(); // I am admin
162162
*/!*
163163

164164
*!*
165-
userGuest.admin?.(); // nothing (no such method)
165+
userGuest.admin?.(); // niente (il metodo non esiste)
166166
*/!*
167167
```
168168
169-
Here, in both lines we first use the dot (`user1.admin`) to get `admin` property, because the user object must exist, so it's safe read from it.
169+
Qui, in entrambe le righe, come prima cosa abbiamo utilizzato il punto (`user1.admin`) per ottenere la proprietà `admin`, poiché l'oggetto `user` deve necessariamente esistere, quindi l'accesso è sicuro.
170170
171-
Then `?.()` checks the left part: if the admin function exists, then it runs (that's so for `user1`). Otherwise (for `user2`) the evaluation stops without errors.
171+
Successivamente `?.()` controlla la parte sinistra: se la funzione `admin` esiste, allora viene eseguita (ciò che accade con `user1`). Altrimenti (con `user2`) la valutazione si interrompe senza errori.
172172
173-
The `?.[]` syntax also works, if we'd like to use brackets `[]` to access properties instead of dot `.`. Similar to previous cases, it allows to safely read a property from an object that may not exist.
173+
La sintassi `?.` funziona anche con le parentesi `[]` (invece del punto `.`). Come nei casi precedenti, possiamo accedere con sicurezza ad una proprietà di un oggetto che potrebbe non esistere.
174174
175175
```js run
176176
let key = "firstName";
@@ -185,36 +185,36 @@ alert( user1?.[key] ); // John
185185
alert( user2?.[key] ); // undefined
186186
```
187187
188-
Also we can use `?.` with `delete`:
188+
Possiamo anche utilizzare `?.` con `delete`:
189189
190190
```js run
191-
delete user?.name; // delete user.name if user exists
191+
delete user?.name; // cancella user.name se l'utente esiste
192192
```
193193
194-
````warn header="We can use `?.` for safe reading and deleting, but not writing"
195-
The optional chaining `?.` has no use at the left side of an assignment.
194+
````warn header="Possiamo utilizzare `?.` per l'accesso e la rimozione sicura, ma non per la scrittura"
195+
La concatenazione opzionale `?.` non ha alcun significato alla sinistra di un'assegnazione.
196196
197-
For example:
197+
Ad esempio:
198198
```js run
199199
let user = null;
200200

201-
user?.name = "John"; // Error, doesn't work
202-
// because it evaluates to undefined = "John"
201+
user?.name = "John"; // Errore, non funziona
202+
// poiché valuta undefined = "John"
203203
```
204204
205-
It's just not that smart.
205+
Non è cosi intelligente.
206206
````
207207
208-
## Summary
208+
## Riepilogo
209209
210-
The optional chaining `?.` syntax has three forms:
210+
La concatenazione opzionale `?.` ha tre forme:
211211
212-
1. `obj?.prop` -- returns `obj.prop` if `obj` exists, otherwise `undefined`.
213-
2. `obj?.[prop]` -- returns `obj[prop]` if `obj` exists, otherwise `undefined`.
214-
3. `obj.method?.()` -- calls `obj.method()` if `obj.method` exists, otherwise returns `undefined`.
212+
1. `obj?.prop` -- ritorna `obj.prop` se `obj` esiste, altrimenti ritorna `undefined`.
213+
2. `obj?.[prop]` -- ritorna `obj[prop]` se `obj` esiste, altrimenti ritorna `undefined`.
214+
3. `obj.method?.()` -- invoca `obj.method()` se `obj.method` esiste, altrimenti ritorna `undefined`.
215215
216-
As we can see, all of them are straightforward and simple to use. The `?.` checks the left part for `null/undefined` and allows the evaluation to proceed if it's not so.
216+
Come possiamo vedere, le tre forme sono semplici da utilizzare. Il costrutto `?.` verifica che la parte sinistra non sia `null/undefined`; se non lo è, permette alla valutazione di proseguire, altrimenti interrompe immediatamente la valutazione.
217217
218-
A chain of `?.` allows to safely access nested properties.
218+
La concatenazione di `?.` permette di accedere in sicurezza a proprietà annidate.
219219
220-
Still, we should apply `?.` carefully, only where it's acceptable that the left part doesn't exist. So that it won't hide programming errors from us, if they occur.
220+
In ogni caso, dovremmo applicare `?.` con prudenza, solamente nei casi in cui è accettabile che la parte sinistra possa non esistere. In questo modo evitiamo di nascondere errori di programmazione, nel caso ce ne siano.

0 commit comments

Comments
 (0)