Quand une même valeur doit être comparée à cinq ou six possibilités, la chaîne de else if devient pénible à lire : le nom de la variable est répété à chaque ligne, et il faut vérifier qu'il s'agit bien de la même à chaque fois.
switch répond à ce cas précis. Il annonce la valeur une fois en tête, puis liste les cas à plat.
Définition
switch évalue l'expression entre parenthèses, la compare à chaque case dans l'ordre, et exécute le bloc du premier qui correspond. La branche default couvre les valeurs qu'aucun cas n'a prévues.
function libelle(statut) {
switch (statut) {
case "paye":
return "Payé";
case "attente":
return "En attente";
default:
return "Statut inconnu";
}
}
console.log(libelle("attente")); // "En attente"Ici chaque cas se termine par un return, ce qui quitte la fonction. Sans lui, il faudrait un break, et son absence est le piège principal de cette structure.
Sans break, l'exécution continue
Un case n'est pas un bloc fermé, c'est un point d'entrée. Une fois qu'un cas correspond, le moteur exécute tout ce qui suit, y compris les cas suivants, jusqu'à rencontrer un break ou la fin du switch.
const jour = "dimanche";
switch (jour) {
case "samedi":
case "dimanche":
console.log("Week-end"); // les deux cas partagent ce bloc
break;
default:
console.log("Jour ouvré");
}Ce comportement rend service quand plusieurs valeurs partagent le même traitement, comme ci-dessus. Il devient un bug dès qu'on oublie un break : deux branches s'exécutent l'une après l'autre, sans le moindre avertissement.
La comparaison est stricte
Le rapprochement entre l'expression et chaque case utilise l'Égalité stricte (===). Le type compte donc autant que la valeur, ce qui surprend quand la donnée vient d'un formulaire ou d'une URL, où tout arrive sous forme de chaîne.
switch ("1") {
case 1:
console.log("nombre");
break;
default:
console.log("aucune correspondance"); // c'est cette branche
}Déclarer une variable avec let ou const dans un case demande d'entourer ce cas d'accolades. Sans elles, tous les cas partagent un seul bloc, et deux déclarations du même nom empêchent le fichier de se charger.
Questions fréquentes
Faut-il toujours écrire un default ?
C'est vivement conseillé. Sans default, une valeur imprévue traverse le switch sans que rien ne se produise, et le programme continue avec une donnée manquante. Une branche qui journalise le cas inattendu, ou qui lève une erreur, transforme un silence en information exploitable.
Quand un objet de correspondance vaut-il mieux ?
Dès que chaque cas se contente d'associer une valeur à une autre. Un Object (objet) dont les clés sont les cas se lit en une ligne, se teste facilement et se modifie sans risque d'oublier un break. Le switch reprend l'avantage quand les branches font autre chose que renvoyer une valeur.
const LIBELLES = { paye: "Payé", attente: "En attente" };
const libelle = (statut) => LIBELLES[statut] ?? "Statut inconnu";
console.log(libelle("paye"), libelle("annule")); // Payé Statut inconnuPeut-on tester des intervalles avec switch ?
Pas directement, puisque chaque case compare une valeur exacte. Le contournement consiste à écrire switch (true) et à placer les comparaisons dans les cas, mais il masque l'intention plus qu'il ne la sert. Pour des intervalles, une chaîne de if et de else reste la forme la plus lisible.