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.
Il problema della “proprietà inesistente”
Se avete appena cominciato a leggere questo tutorial e a imparare JavaScript, forse questo problema non lo avete ancora affrontato, ma è piuttosto comune.
Ad esempio, ipotizziamo di avere un oggetto user, in cui sono memorizzate le informazioni relative ai nostri utenti.
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.
In questo caso, quando proviamo ad accedere a user.address.street, e l’utente non possiede un indirizzo, avremo un errore:
let user = {}; // un utente senza la proprietà "address"
alert(user.address.street); // Errore!
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.
Nella maggior parte dei casi, preferiremmo avere undefined piuttosto di un errore (in questo caso con il significato “nessuna via”).
… 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 esiste.
// document.querySelector('.elem') è null se non esiste l'elemento
let html = document.querySelector('.elem').innerHTML; // errore se è null
Di nuovo, se un elemento 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.
Come possiamo farlo?
La soluzione più ovvia sarebbe di controllare il valore utilizzando if o l’operatore condizionale ? prima di accedere alle proprietà, come nell’esempio:
let user = {};
alert(user.address ? user.address.street : undefined);
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.
Ad esempio, proviamo a recuperare il valore di user.address.street.name.
Dobbiamo verificare sia user.address che user.address.street:
let user = {}; // l'utente non ha address
alert(user.address ? user.address.street ? user.address.street.name : null : null);
Questo è semplicemente terribile, un codice del genere potrebbe essere difficile da comprendere.
Ci sarebbe un modo migliore per riscriverlo, utilizzando l’operatore &&:
let user = {}; // l'utente non ha address
alert( user.address && user.address.street && user.address.street.name ); // undefined (nessun errore)
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.
Come potete vedere, i nome delle proprietà sono ancora duplicate nel codice. Ad esempio, nel codice sopra, user.address è ripetuto tre volte.
Questo è il motivo per cui la concatenazione opzionale ?. è stata aggiunta al linguaggio. Per risolvere questo problema una volta per tutte!
Concatenazione opzionale
La concatenazione opzionale ?. interrompe la valutazione se il valore prima di ?. è undefined o null, e ritorna undefined.
D’ora in poi, in questo articolo, per brevità diremo che qualcosa “esiste” se non è né null né undefined.
In altre parole,