Menu

Operatore ?? in JavaScript: valori predefiniti fatti bene

Come l'operatore ?? sceglie un valore predefinito solo quando un valore è null o undefined, e perché nella pratica batte ||.

Questa pagina include editor eseguibili: modifica, esegui e vedi subito l'output.

Un valore predefinito più intelligente

JavaScript ha sempre avuto una scorciatoia per i valori predefiniti: value || fallback. Funziona quasi sempre, ma ha un difetto di fabbrica: considera "mancante" qualsiasi valore falsy. 0, '' e false fanno scattare tutti il ripiego, anche quando sono la risposta giusta.

L'operatore di nullish coalescing ?? risolve proprio questo. Ricorre al ripiego solo con null o undefined:

0 e '' sopravvivono. null e undefined no. Ecco tutto l'operatore.

Perché || non basta

Ecco il bug classico che ?? è nato per evitare:

L'utente ha chiesto volume 0 (silenzio) e un nickname vuoto. Entrambi i valori sono stati sovrascritti senza avviso, perché || non distingue tra "mancante" e "falsy".

Passa a ??:

Ora 0 e '' passano intatti, e solo i campi che mancano davvero ricevono il valore predefinito. È quasi sempre quello che vuoi.

Il modello mentale

?? si pone una sola domanda: il lato sinistro è null o undefined? Nient'altro conta.

Valore a sinistrasin || des restituiscesin ?? des restituisce
nulldesdes
undefineddesdes
0dessin (0)
''dessin ('')
falsedessin (false)
NaNdessin (NaN)
qualsiasi oggettosinsin

Scegli ?? quando i tuoi dati contengono valori falsy con un significato. Scegli || quando vuoi davvero scartare tutto ciò che è falsy (stringhe vuote, contatori a zero e così via): quel caso esiste, ma è più raro di quanto si pensi.

Valutazione in cortocircuito

Come || e &&, anche ?? valuta in cortocircuito. Se il lato sinistro non è nullish, il lato destro non viene nemmeno eseguito:

expensiveDefault() viene eseguita una sola volta, per b. È utile quando il ripiego è una chiamata di funzione, una richiesta di rete o qualsiasi altra cosa che preferisci saltare quando non serve.

In coppia con l'optional chaining

?? e ?. sono stati introdotti insieme in ES2020 e sono pensati per lavorare in squadra. L'optional chaining percorre un cammino che potrebbe mancare e restituisce undefined se un passaggio non c'è; il nullish coalescing poi inserisce un valore predefinito sensato:

Senza questa coppia, lo stesso codice diventa una brutta catena di controlli && o un try/catch. Con loro, accesso sicuro e valori predefiniti sensati stanno in una riga.

Assegnazione nullish: ??=

a ??= b assegna b ad a solo quando a è null o undefined. È l'operatore di assegnazione logica nullish e valuta in cortocircuito: se a ha già un valore, il lato destro non viene valutato.

Nota che verbose: false e retries: 0 vengono conservati: ??= riempie solo ciò che manca davvero. Confrontalo con ||=, che li sovrascriverebbe entrambi.

Precedenza e la regola delle parentesi

?? si rifiuta di proposito di mescolarsi con || o && senza parentesi. Questo lancia un SyntaxError:

const x = a || b ?? c;   // SyntaxError

Chi ha progettato il linguaggio ha ritenuto la precedenza abbastanza ambigua da obbligarti a chiarirla. Aggiungi le parentesi e tutto funziona:

Raggruppamenti diversi, risultati diversi. Le parentesi non sono decorative: dicono a chi leggerà il codice in futuro (e al parser) cosa intendevi.

Non è come un parametro predefinito

I parametri predefiniti nella firma di una funzione hanno una regola tutta loro: scattano solo quando l'argomento è undefined, non null. È una differenza sottile rispetto a ??, che tratta i due casi allo stesso modo.

Se vuoi che anche null faccia scattare il ripiego, usa ?? nel corpo della funzione:

Una piccola differenza, facile da trascurare quando un'API ti restituisce null per dire "nessun valore impostato".

Quando usare l'operatore ??

Usa ?? come operatore predefinito, a meno che tu non abbia un motivo preciso per non farlo. È quello che rispecchia meglio il comportamento reale dei dati: 0, '' e false di solito sono valori veri da conservare, e solo i dati davvero mancanti meritano un ripiego. Riserva || ai casi in cui vuoi davvero sostituire qualsiasi valore falsy.

Prossimo passo: le classi

Con questo chiudiamo il blocco su oggetti e array: hai gli strumenti per costruire e percorrere strutture di dati in sicurezza. Il prossimo capitolo passa all'organizzazione del comportamento: classi, ereditarietà e il sistema dei prototipi che c'è sotto.

Domande frequenti

Cos'è l'operatore di nullish coalescing in JavaScript?

?? restituisce l'operando di destra solo quando quello di sinistra è null o undefined. Negli altri casi restituisce il valore di sinistra invariato. L'espressione value ?? fallback è il modo standard per fornire un valore predefinito senza inciampare in valori falsy ma validi, come 0 o ''.

Qual è la differenza tra ?? e || in JavaScript?

|| ricorre al valore di ripiego con qualsiasi valore falsy: 0, '', false, NaN, null e undefined. ?? lo fa solo con null e undefined. Se nei tuoi dati 0 o una stringa vuota sono valori legittimi, usa ??. Se vuoi davvero scartare ogni valore falsy, || resta la scelta giusta.

Si può combinare ?? con l'optional chaining?

Sì, ed è un abbinamento molto comune. user?.settings?.theme ?? 'light' percorre la catena in modo sicuro, restituisce undefined se manca qualcosa lungo il percorso e poi applica 'light'. I due operatori sono arrivati insieme in ES2020 proprio per supportare questo schema.

Cosa fa l'operatore ??=?

a ??= b assegna b ad a solo se a vale null o undefined. È l'assegnazione logica nullish, una forma abbreviata di a = a ?? b, ma con cortocircuito: se a ha già un valore, la parte destra non viene nemmeno valutata. Utile per riempire i valori predefiniti mancanti in un oggetto di opzioni.

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA