JavaScript Optional Chaining (?.)
Impara l'operatore di optional chaining (?.) in JavaScript per accedere in sicurezza a proprietà annidate, chiamare metodi e leggere chiavi dinamiche.
L'operatore di optional chaining ?. è un modo breve e sicuro per leggere un valore in profondità all'interno di una catena di object collegati, quando uno dei link della catena potrebbe non esistere. Invece di generare un errore, si interrompe semplicemente e restituisce undefined. Questo capitolo illustra il problema che risolve, le tre forme che assume e le poche regole necessarie per utilizzarlo correttamente.
Il Problema: Lettura di Proprietà Mancanti
Immagina di avere un object user e di voler leggere la città da un object address annidato. Se address è assente, accedere a una proprietà su di esso genera un errore:
let user = {}; // a user without an address
console.log(user.address.city);
// TypeError: Cannot read properties of undefined (reading 'city')Il motivo è che user.address è undefined, e tentare di leggere .city da undefined non è consentito. Questa è una situazione comune quando i dati provengono da un'API, un form o un database in cui alcuni campi sono facoltativi.
Prima che ?. esistesse, gli sviluppatori aggiravano il problema con catene && o controlli annidati. Questi funzionano, ma sono verbosi e ripetono i nomi delle proprietà:
let user = {};
// The old way with the && operator
let city = user && user.address && user.address.city;
console.log(city); // undefined
// Or with an even longer ternary
let city2 = user ? (user.address ? user.address.city : undefined) : undefined;
console.log(city2); // undefinedCome Funziona l'Optional Chaining
L'operatore di optional chaining ?. interrompe la valutazione se il valore che lo precede è null o undefined, e restituisce undefined invece di generare un errore. Questo comportamento si chiama short-circuiting.
Ecco la stessa operazione di lettura, ora sicura e leggibile:
Quando user.address è undefined, l'espressione user?.address?.city restituisce silenziosamente undefined. Quando i dati sono presenti, la catena legge fino in fondo fino a city.
?. tratta solo null e undefined come "mancanti". Altri valori falsy come 0, '' (string vuota) o false sono valori reali, quindi la catena continua normalmente attraverso di essi.
Protegge Solo il Valore alla Sua Sinistra
Questa è la regola più importante, quella che i principianti sbagliano più spesso. Il ?. controlla solo il valore immediatamente alla sua sinistra, non l'intera catena.
Considera a?.b.c:
- Se
aènulloundefined, l'intera espressione va in short-circuit e restituisceundefined. - Ma se
aesiste ebènulloundefined, allora.cè ancora un accesso normale — e genera un errore.
let a = { b: null };
console.log(a?.b); // null — fine, a exists
console.log(a?.b.c); // TypeError: Cannot read properties of null (reading 'c')La soluzione è posizionare ?. in ogni punto in cui un valore può legittimamente essere assente:
let a = { b: null };
console.log(a?.b?.c); // undefined — no errorQuindi la regola è semplice: metti ?. direttamente dopo ogni valore che potrebbe non essere presente, non solo all'inizio della catena.
Lo Short-Circuiting Interrompe l'Intera Catena
Quando la parte prima di ?. è null o undefined, il resto dell'espressione non viene valutato affatto. Questo include eventuali chiamate a funzioni e ulteriori accessi a proprietà che vengono dopo.
Questa è una garanzia utile: nulla dopo un link mancante ha la possibilità di essere eseguito o causare effetti collaterali.
Le Tre Forme dell'Optional Chaining
?. non è un operatore autonomo — è un costrutto sintattico che si presenta in tre forme, una per ciascun modo di accedere a un valore.
?. per l'Accesso alle Proprietà
Usa obj?.prop per leggere una proprietà quando obj potrebbe essere null o undefined.
let user = { name: 'John' };
console.log(user?.name); // John
console.log(user?.surname); // undefined (key missing, but no error)?.() per Chiamare Metodi
Usa obj.method?.() per chiamare un metodo solo se esiste. Questo è utile quando un object può o meno implementare un determinato metodo.
Se greet non è una funzione (perché è assente), ?.() salta la chiamata e restituisce undefined invece di generare TypeError: greet is not a function.
?.[] per Chiavi Dinamiche
Usa obj?.[key] quando leggi una proprietà con notazione a parentesi — ad esempio, una chiave dinamica memorizzata in una variabile.
let user = { name: 'Alice' };
let key = 'name';
console.log(user?.[key]); // Alice
let nobody = null;
console.log(nobody?.[key]); // undefined (no error)L'Optional Chaining è per la Lettura, Non per la Scrittura
Puoi usare ?. per leggere un valore e anche per eliminare (delete) una proprietà in modo sicuro. Ma non puoi usarlo sul lato sinistro di un'assegnazione.
let user = null;
// Reading is fine
console.log(user?.name); // undefined
// Deleting is fine — delete is skipped if user is null
delete user?.name; // no error
// Assignment does NOT work — this is a syntax error
// user?.name = 'John'; // SyntaxErrorIl motivo è che non c'è nulla di significativo a cui assegnare quando il lato sinistro è assente, quindi il linguaggio non lo consente.
Non Abusare dell'Optional Chaining
?. è uno strumento preciso: usalo solo dove il valore alla sua sinistra è genuinamente facoltativo. Ricorrervi ovunque è un errore, perché può nascondere bug reali.
Ad esempio, se scrivi male il nome di una proprietà, ?. restituirà silenziosamente undefined invece di farti notare il problema:
let user = { name: 'John' };
console.log(user?.nmae); // undefined — typo hidden, no error to alert youSe una variabile come user deve sempre esistere (ad esempio, è un argomento obbligatorio), accedici direttamente con user.address?.city, non con user?.address?.city. In questo modo, un user genuinamente mancante genera ancora un errore in anticipo, il che ti aiuta a individuare i bug invece di mascherarli.
Abbinamento con il Nullish Coalescing
L'optional chaining restituisce undefined quando un link è mancante, il che si abbina perfettamente con l'operatore di nullish coalescing ?? per fornire un valore predefinito.
Qui user?.name restituisce undefined, e ?? interviene per fornire il valore di fallback 'Anonymous'. Questa combinazione è uno degli usi più comuni nel mondo reale di ?..
Supporto dei Browser
L'optional chaining fa parte della specifica ES2020. È supportato in tutti i browser moderni (Chrome, Firefox, Safari ed Edge) e in Node.js 14 e versioni successive, quindi puoi usarlo senza un transpiler negli ambienti attuali. Per approfondire i valori che controlla, consulta tipi di dati JavaScript e metodi degli object e this.