Chapitre 317 minDébutant
Conditions et boucles : if, switch, for…of, while
Par Josselyn C., prof de BTS SIO. Mis à jour le .
À la fin de ce chapitre, tu sauras
- écrire une condition avec
if, le ternaire ouswitch; - parcourir un tableau avec
for…ofet un objet avecfor…in; - choisir la boucle adaptée et éviter les boucles infinies ;
- interrompre une boucle avec
breakou passer un tour aveccontinue.
4 exercices corrigés
Les conditions (if, switch, l'opérateur ternaire) choisissent quel code exécuter ; les boucles (for, for…of, for…in, while) répètent un bloc. Ce chapitre montre leur syntaxe en JavaScript et les pièges propres au langage. Si les notions de condition et de boucle sont encore floues pour toi, commence par les chapitres Si, alors, sinon et Boucles pour, tant que du cours d'algorithmique : on n'y revient pas ici.
Les exemples utilisent le stock de Gestock, rangé dans un tableau d'objets. Tu verras les tableaux et les objets en détail aux chapitres 5 et 6 ; pour l'instant, retiens que pieces[0] est la première pièce et que pieces[0].quantite est sa quantité.
const pieces = [
{ ref: 'SSD-512', nom: 'SSD NVMe 512 Go', categorie: 'Stockage', quantite: 12, seuil: 5, prix: 42.9 },
{ ref: 'RAM-16', nom: 'Barrette DDR4 16 Go', categorie: 'Mémoire', quantite: 3, seuil: 4, prix: 38.5 },
{ ref: 'CHG-65', nom: 'Chargeur USB-C 65 W', categorie: 'Alimentation', quantite: 0, seuil: 2, prix: 24 },
{ ref: 'ECR-156', nom: 'Dalle 15,6 pouces', categorie: 'Écran', quantite: 2, seuil: 1, prix: 89 },
{ ref: 'PAT-01', nom: 'Pâte thermique', categorie: 'Consommable', quantite: 25, seuil: 10, prix: 6.5 },
];
if, else if, else
function statut(quantite, seuil) {
if (quantite === 0) {
return 'rupture';
} else if (quantite <= seuil) {
return 'alerte';
} else {
return 'ok';
}
}
statut(12, 5); // 'ok'
statut(3, 4); // 'alerte'
statut(0, 2); // 'rupture'
La condition s'écrit entre parenthèses, le bloc entre accolades. Les conditions sont testées dans l'ordre et seul le premier bloc dont la condition est vraie s'exécute : c'est pour cela que la rupture (quantite === 0) est testée avant l'alerte, sinon une pièce à 0 serait classée « alerte » (0 est bien inférieur au seuil).
Les accolades sont facultatives quand le bloc ne contient qu'une instruction (if (quantite === 0) return 'rupture';). Garde-les dès que tu hésites : une deuxième ligne ajoutée plus tard sans accolades s'exécuterait toujours, quel que soit le résultat du test.
Pour combiner des conditions, utilise && (et), || (ou) et ! (non), en ajoutant des parenthèses dès que tu mélanges && et || :
const p = pieces[1];
if (p.quantite <= p.seuil && (p.categorie === 'Mémoire' || p.categorie === 'Stockage')) {
console.log(`Commande urgente : ${p.ref}`); // Commande urgente : RAM-16
}
Le retour anticipé : éviter les if imbriqués
Quand une fonction doit vérifier plusieurs choses avant de travailler, sors dès qu'une vérification échoue. Le code se lit de haut en bas au lieu de s'enfoncer dans des else :
function retirerUnite(piece) {
if (!piece) return 'Pièce introuvable';
if (piece.quantite === 0) return `${piece.ref} est en rupture`;
piece.quantite -= 1;
return `${piece.ref} : il en reste ${piece.quantite}`;
}
L'opérateur ternaire
Le ternaire condition ? valeurSiVrai : valeurSiFaux est un if…else qui produit une valeur. Il sert à choisir une valeur dans une expression, pas à enchaîner des actions :
const q = 1;
const texte = q > 1 ? `${q} pièces` : `${q} pièce`; // '1 pièce'
N'imbrique pas les ternaires (a ? b : c ? d : e) : au-delà de deux cas, un if ou un switch se lit mieux.
switch : choisir parmi plusieurs valeurs
switch compare une valeur à plusieurs cas avec l'égalité stricte === :
function delaiLivraison(categorie) {
switch (categorie) {
case 'Stockage':
case 'Mémoire':
return 2; // deux cas regroupés
case 'Écran':
return 7;
default:
return 3; // toutes les autres catégories
}
}
delaiLivraison('Mémoire'); // 2
delaiLivraison('Alimentation'); // 3
Dans une fonction, return sort directement du switch. Hors d'une fonction, chaque cas doit se terminer par break, sinon l'exécution continue dans le cas suivant (on parle de fall-through) :
let libelle = '';
switch (1) {
case 1:
libelle = 'un'; // pas de break…
case 2:
libelle = 'deux'; // … donc on exécute aussi cette ligne
break;
default:
libelle = '?';
}
console.log(libelle); // 'deux'
Quand chaque cas se contente de donner une valeur, un objet de correspondance est souvent plus court qu'un switch :
const DELAIS = { Stockage: 2, Mémoire: 2, Écran: 7 };
const delai = DELAIS['Écran'] ?? 3; // 7
const autre = DELAIS['Alimentation'] ?? 3; // 3 : catégorie absente, valeur par défaut
La boucle for classique
La boucle for à compteur répète un bloc tant qu'une condition est vraie. Elle a trois parties : l'initialisation, la condition, l'incrément.
let nbAlertes = 0;
for (let i = 0; i < pieces.length; i++) {
if (pieces[i].quantite <= pieces[i].seuil) {
nbAlertes++;
}
}
console.log(nbAlertes); // 2 (RAM-16 et CHG-65)
Les indices d'un tableau vont de 0 à pieces.length - 1 : la condition est donc i < pieces.length, avec un < strict. Écrire i <= pieces.length fait un tour de trop, où pieces[i] vaut undefined, et undefined.quantite arrête le script sur une TypeError.
for…of : parcourir un tableau ou une chaîne
Quand tu n'as pas besoin de l'indice, for…of donne directement chaque élément. C'est la boucle à utiliser par défaut sur un tableau :
for (const p of pieces) {
console.log(`${p.ref} : ${statut(p.quantite, p.seuil)}`);
}
SSD-512 : ok
RAM-16 : alerte
CHG-65 : rupture
ECR-156 : ok
PAT-01 : ok
La variable de boucle peut être une const : elle est recréée à chaque tour. for…of parcourt aussi les caractères d'une chaîne (for (const lettre of 'RAM') donne R, A, M), les Map et les Set (chapitre 6). Si tu as besoin de l'indice en plus, utilise entries() :
for (const [i, p] of pieces.entries()) {
console.log(`${i + 1}. ${p.ref}`); // 1. SSD-512, 2. RAM-16…
}
for…in : parcourir les propriétés d'un objet
for…in parcourt les noms des propriétés d'un objet :
const piece = pieces[0];
for (const cle in piece) {
console.log(`${cle} = ${piece[cle]}`);
}
ref = SSD-512
nom = SSD NVMe 512 Go
categorie = Stockage
quantite = 12
seuil = 5
prix = 42.9
while et do…while
while répète tant qu'une condition est vraie, quand on ne connaît pas le nombre de tours à l'avance. Combien de jours avant de passer sous le seuil, si l'atelier consomme 3 SSD par jour ?
let stock = 12;
let jours = 0;
while (stock > 5) {
stock -= 3;
jours++;
}
console.log(stock, jours); // 3 3
do…while exécute le bloc une première fois avant de tester la condition : utile pour redemander une saisie jusqu'à ce qu'elle soit correcte, rare dans une page web où l'on attend plutôt un événement.
break et continue
break sort immédiatement de la boucle ; continue passe au tour suivant.
for (const p of pieces) {
if (p.quantite === 0) {
console.log(`Première rupture : ${p.ref}`); // Première rupture : CHG-65
break;
}
}
let unites = 0;
for (const p of pieces) {
if (p.categorie === 'Consommable') continue; // on ignore la pâte thermique
unites += p.quantite;
}
console.log(unites); // 17
Quelle boucle choisir ?
| Besoin | Écriture | Exemple |
|---|---|---|
| Chaque élément d'un tableau | for (const p of pieces) | Afficher chaque pièce |
| L'élément et son indice | for (const [i, p] of pieces.entries()) | Numéroter les lignes |
| Un compteur, un pas différent de 1 | for (let i = 0; i < n; i += 2) | Une ligne sur deux |
| Les propriétés d'un objet | for (const cle in objet) ou Object.entries | Afficher une fiche |
| Répéter jusqu'à une condition | while (condition) | Simuler une consommation |
| Transformer, filtrer, résumer un tableau | map, filter, reduce | Chapitre 5 |
Dans un code JavaScript moderne, les boucles explicites reculent au profit des méthodes de tableau du chapitre 5, plus courtes et plus lisibles. Mais elles restent indispensables dès qu'il faut s'arrêter en route (break), et ce sont elles que tu écris en algorithmique et à l'écrit de l'E7, où le code se lit et s'écrit sur papier.
Fil rouge : le statut de chaque pièce
Gestock affichera un statut pour chaque pièce. Avec la fonction statut de ce chapitre et une boucle, compte les pièces de chaque statut :
let ok = 0;
let alerte = 0;
let rupture = 0;
for (const p of pieces) {
switch (statut(p.quantite, p.seuil)) {
case 'rupture':
rupture++;
break;
case 'alerte':
alerte++;
break;
default:
ok++;
}
}
console.log(`ok : ${ok}, alerte : ${alerte}, rupture : ${rupture}`);
// ok : 3, alerte : 1, rupture : 1
Attention à la différence de vocabulaire : ici, CHG-65 compte comme « rupture » et non comme « alerte ». Dans le reste du cours, une pièce est en alerte dès que sa quantité est inférieure ou égale au seuil, rupture comprise : RAM-16 et CHG-65.
Exercices
Exercice 1 sur 4 Trace d'une boucle Réussi À revoir
Qu'affiche ce code ? Fais la trace tour par tour avant de vérifier.
let sortie = '';
for (let i = 1; i <= 10; i++) {
if (i % 4 === 0) break;
if (i % 2 === 0) continue;
sortie += i + ' ';
}
console.log(sortie);
Voir la réponseMasquer la réponse de l'exercice 1
1 3 (avec un espace final).
i = 1: ni multiple de 4, ni pair, on ajoute'1 '.i = 2: pair,continue, on passe.i = 3: on ajoute'3 '.i = 4: multiple de 4,break, la boucle s'arrête.
Tu avais trouvé ?
Exercice 2 sur 4 Remise selon la quantité Réussi À revoir
Réparinfo obtient une remise de son fournisseur selon le nombre d'unités commandées : rien en dessous de 10, 5 % de 10 à 49, 10 % à partir de 50. Écris la fonction tauxRemise(unites) qui renvoie 0, 5 ou 10, puis donne son résultat pour 9, 10, 49 et 50.
Voir la réponseMasquer la réponse de l'exercice 2
function tauxRemise(unites) {
if (unites >= 50) return 10;
if (unites >= 10) return 5;
return 0;
}
tauxRemise(9) vaut 0, tauxRemise(10) vaut 5, tauxRemise(49) vaut 5, tauxRemise(50) vaut 10. En testant le plus grand seuil d'abord, chaque condition n'a qu'une borne à vérifier. Les valeurs 10, 49 et 50 sont les cas limites : ce sont elles qu'il faut toujours essayer.
Tu avais trouvé ?
Exercice 3 sur 4 Le bon outil Réussi À revoir
Pour chaque besoin, indique la structure la plus adaptée : if, ternaire, switch (ou objet de correspondance), for…of, for…in, while.
- Afficher « pièce » ou « pièces » selon la quantité.
- Associer à chaque catégorie une couleur d'étiquette.
- Afficher toutes les propriétés d'une pièce sous la forme
clé : valeur. - Afficher chaque pièce du stock.
- Diviser un prix par 2 tant qu'il dépasse 100 €.
- Refuser une saisie vide, sinon l'enregistrer.
Voir la réponseMasquer la réponse de l'exercice 3
- Le ternaire : on choisit une valeur dans une expression.
- Un
switch, ou mieux un objet de correspondance{ Stockage: 'bleu', … }. for…in(ouObject.entriesavecfor…of).for…of.while: on ne sait pas d'avance combien de divisions il faudra.if…else.
Tu avais trouvé ?
Exercice 4 sur 4 Corriger la boucle Réussi À revoir
Ce code doit afficher la référence de chaque pièce, mais il s'arrête sur une erreur après la dernière. Quelle erreur affiche la console ? Corrige-le, puis réécris-le avec for…of.
for (let i = 0; i <= pieces.length; i++) {
console.log(pieces[i].ref);
}
Voir la réponseMasquer la réponse de l'exercice 4
Avec 5 pièces, i va jusqu'à 5 inclus. pieces[5] vaut undefined, et la console affiche TypeError: Cannot read properties of undefined (reading 'ref').
Correction : i < pieces.length. En for…of, l'erreur devient impossible :
for (const p of pieces) {
console.log(p.ref);
}
Tu avais trouvé ?