La forma di un'istruzione if
Un'istruzione if esegue un blocco di codice solo quando una condizione è vera. La forma è una parola chiave, una condizione tra parentesi e un blocco tra parentesi graffe:
La condizione age >= 18 vale true, quindi il blocco viene eseguito. Se age fosse 16, la condizione sarebbe false e JavaScript salterebbe completamente il blocco.
Le parentesi graffe sono tecnicamente facoltative quando il blocco contiene una sola istruzione, ma usale sempre. Gli if senza graffe sono una classica fonte di bug quando qualcuno in seguito aggiunge una seconda riga e dimentica che in realtà non è dentro il blocco.
else: il ramo alternativo
Abbina if a else per eseguire codice diverso quando la condizione è falsa:
Viene eseguito esattamente uno dei due rami. Mai entrambi, mai nessuno. else non ha una condizione propria: è il caso di riserva per "l'if era falso".
else if: scegliere tra più opzioni
Quando hai più di due casi, concatenali con else if. JavaScript controlla ogni condizione in ordine e si ferma alla prima vera:
Viene eseguito un solo ramo. Appena una condizione corrisponde, le altre vengono saltate, anche se sarebbero vere anche loro. Per questo l'ordine conta: se invertissi la catena controllando prima score >= 60, chiunque superi 60 prenderebbe una D.
L'else finale è facoltativo, ma includerlo rende chiara la tua intenzione: "se non corrisponde nient'altro, fai questo".
Le condizioni possono essere qualsiasi espressione
Ciò che sta tra le parentesi non deve per forza essere un confronto. Può essere qualsiasi espressione: JavaScript converte il risultato in un booleano.
Le stringhe non vuote sono truthy. 0 e le stringhe vuote sono falsy, quindi items.length che vale 0 porta al ramo else. È l'idioma standard di JavaScript per "controlla se c'è qualcosa".
L'elenco completo dei valori falsy è breve e vale la pena impararlo a memoria: false, 0, -0, 0n, "", null, undefined e NaN. Tutto il resto è truthy, compresi "0", "false", [] e {}. Gli ultimi due colgono molti di sorpresa.
Combinare condizioni: && e ||
Usa && (e) e || (o) per combinare le condizioni:
&& richiede che entrambi i lati siano truthy. || ne richiede almeno uno. Entrambi fanno short-circuit: && si ferma al primo valore falsy, || al primo truthy. Questo conta quando la seconda condizione ha un effetto collaterale o lancerebbe un errore: user && user.name restituisce tranquillamente undefined se user è null, senza far saltare tutto.
Racchiudi la logica mista tra parentesi per rendere evidente la precedenza:
Senza le parentesi, && ha la precedenza su ||, il che di solito è l'opposto di come si legge in modo naturale.
== contro === (usa ===)
Quando controlli l'uguaglianza dentro un if, usa === e !==, non == e !=:
== converte i tipi prima di confrontare, e questo porta a sorprese come "" == 0 che vale true e null == undefined che vale true. === confronta senza coercizione: stesso tipo e stesso valore. Usa === di default. L'unica eccezione comune è x == null, che controlla sia null sia undefined in un colpo solo.
L'operatore ternario
Per scegliere tra due valori, l'operatore ternario condition ? a : b è spesso più pulito di un if/else completo:
Il ternario è un'espressione: produce un valore. È questa la differenza chiave rispetto a if/else, che è un'istruzione. Usa il ternario quando ti serve il risultato (assegnare una variabile, restituire un valore, costruire una stringa). Usa if/else quando esegui effetti collaterali.
Puoi concatenare i ternari, ma la leggibilità crolla:
// Non fare così:
const grade = score >= 90 ? "A" : score >= 80 ? "B" : score >= 70 ? "C" : "F";
Se ti ritrovi a concatenarli, torna a else if.
if annidati contro else if piatti
A volte una condizione ha senso solo dentro un'altra. Per questo annidare va benissimo:
Ma annidare su tre o quattro livelli è un campanello d'allarme. Appiattisci il codice con return anticipati o con una condizione combinata:
I return anticipati mantengono ogni ramo corto e allo stesso livello di indentazione. Molto più facile da scorrere di una piramide di if annidati.
Un errore comune: l'assegnazione dentro l'if
= assegna. === confronta. Confonderli dentro una condizione è un bug classico:
status = "done" assegna "done" a status e vale "done", che è truthy: quindi il blocco viene eseguito sempre, e hai sovrascritto la variabile senza accorgertene. I linter lo segnalano. Lo strict mode no. Fai attenzione e usa === quando vuoi confrontare.
Prossimo passo: switch
Quando confronti un valore con molte possibili corrispondenze, una lunga catena di else if inizia a sembrare ripetitiva. L'istruzione switch di JavaScript è pensata proprio per questo caso, e ha le sue particolarità legate a break e al fall-through, che vedrai nella prossima pagina.
Domande frequenti
Come si scrive un'istruzione if/else in JavaScript?
Metti una condizione tra parentesi dopo if, poi un blocco tra parentesi graffe. Aggiungi else e un altro blocco per il caso alternativo. Esempio: if (age >= 18) { console.log('adult'); } else { console.log('minor'); }. La condizione può essere qualsiasi espressione: JavaScript la converte in un booleano.
Qual è la differenza tra else if e if annidati in JavaScript?
else if concatena le condizioni in modo che venga eseguito un solo ramo: JavaScript controlla ogni condizione in ordine e si ferma alla prima vera. Gli if annidati ne mettono uno dentro l'altro, di solito per controllare una seconda condizione solo quando la prima era vera. Una catena piatta di else if è quasi sempre più leggibile di tanti if annidati.
Quando usare l'operatore ternario invece di if/else?
Usa il ternario condition ? a : b quando scegli tra due valori dentro un'espressione: assegnare una variabile, restituire un valore da una funzione, costruire una stringa. Resta su if/else quando i rami eseguono istruzioni con effetti collaterali o quando uno dei due lati è più di una breve espressione. I ternari concatenati diventano illeggibili molto in fretta.
Perché if (0) si comporta diversamente da if (false) in JavaScript?
Non è così: entrambi saltano il blocco. JavaScript converte la condizione in booleano, e 0, '', null, undefined, NaN e false sono tutti falsy. La trappola è che valori come '0' (una stringa non vuota) e [] (un array vuoto) sono truthy, e questo sorprende chi arriva da altri linguaggi.