Question 1Quand tu parcours orderIds.entries() avec for...of, que vaut index au premier tour ?
Boucles — for, for...of et for...in
Les boucles JavaScript : for pour compter, for...of pour les éléments, for...in pour les clés, et les boucles imbriquées.
Pour afficher le prix de chaque article commandé sur sa propre ligne, il faudrait écrire la même ligne 3 fois pour 3 articles, et 10 fois pour 10. Le nombre d'articles dépend des données : impossible de savoir à l'avance combien de lignes il te faudra.
Cet article couvre for, qui répète en comptant, for...of, qui te donne les éléments un par un, et for...in, qui parcourt les clés.
Répéter du code pour chaque article — les trois expressions de for
Imaginons que tu veuilles afficher le nom des articles d'une commande, un par ligne. Si tu les écris un à un, en commençant par console.log(orderLines[0]), il faudra ajouter une ligne dès que la commande passe à 4 articles, et modifier le code chaque fois que le nombre change.
Une boucle for (une instruction qui répète le même code en comptant) prend entre ses parenthèses trois expressions séparées par des points-virgules, et le code à répéter se place entre les accolades. Ce qui se trouve entre ces accolades s'appelle le corps. De gauche à droite, les trois expressions sont l'initialisation, la condition et la mise à jour : la condition est testée avant d'entrer dans le corps, et la mise à jour s'exécute après le corps.
i++ a le même sens que i = i + 1. Comme sa valeur change à chaque tour, i est déclaré avec let.
const orderLines = ["Mug", "Carnet", "Stylo bille"]; // noms des articles de la commande
// i part de 0 et augmente de 1 avec i++ jusqu'à atteindre le nombre d'articles
for (let i = 0; i < orderLines.length; i++) {
// Les index commencent à 0 : on affiche i + 1 pour compter à partir de l'article 1
console.log(`Article ${i + 1} : ${orderLines[i]}`);
}
// Article 1 : Mug
// Article 2 : Carnet
// Article 3 : Stylo bille
console.log(`Articles affichés : ${orderLines.length}`); // Articles affichés : 3
L'initialisation ne s'exécute qu'une fois, tout au début ; la condition s'exécute avant le corps, et la mise à jour après le corps. Au tour où la condition devient fausse, la boucle se termine sans exécuter le corps.
Tester la condition, exécuter le corps puis la mise à jour : l'ensemble forme un tour (une itération). Comme la mise à jour s'exécute après le corps, i est toujours égal au nombre de fois où le corps s'est déjà exécuté en entier ; au premier tour, le corps s'exécute donc avec i encore à 0.
Le tableau ci-dessous montre i et le test de la condition à chaque tour.
| Tour | Valeur de i et condition | Ce qui se passe dans le corps |
|---|---|---|
| Tour 1 | i = 0 / 0 < 3 est vrai | Article 1 : Mug |
| Tour 2 | i = 1 / 1 < 3 est vrai | Article 2 : Carnet |
| Tour 3 | i = 2 / 2 < 3 est vrai | Article 3 : Stylo bille |
| Début du tour 4 | i = 3 / 3 < 3 est faux | Le corps ne s'exécute pas, la boucle se termine |
Lire au-delà de la fin d'un tableau donne undefined
Si tu écris la condition i <= orderLines.length, tu obtiens un tour de trop à la fin, qui lit orderLines[3] — un élément qui n'existe pas. Tout ce qui est hors limites vaut undefined : tu verras donc « Article 4 : undefined », et si la boucle additionne des prix, le résultat devient NaN. Ne fais tourner la boucle que tant que l'index est inférieur au nombre d'articles.
Récupérer chaque élément directement — for...of et entries
Prenons une liste de numéros de commande en attente d'expédition, à traiter l'un après l'autre. Avec for, il faut déclarer une variable d'index, écrire la condition et la mise à jour, puis lire chaque numéro avec orderIds[i] — et une faute de frappe dans l'index suffit à lire le mauvais élément.
for...of (une instruction qui prend un par un les éléments d'un tableau ou d'un autre itérable et place chacun dans une variable) s'écrit for (const orderId of orderIds), avec seulement la déclaration et le tableau entre les parenthèses.
Si tu as aussi besoin de la position, boucle sur orderIds.entries(). À chaque tour, tu obtiens une paire comme [0, "A-1001"], que tu décomposes avec des crochets : [index, orderId].
const orderIds = ["A-1001", "A-1002", "A-1003"]; // numéros de commande en attente d'expédition
// orderId contient l'élément lui-même (aucun index en vue)
for (const orderId of orderIds) {
console.log(`En attente d'expédition : ${orderId}`);
}
// En attente d'expédition : A-1001 … (3 lignes)
// Si tu as aussi besoin de l'index, récupère des paires avec entries()
for (const [index, orderId] of orderIds.entries()) {
console.log(`#${index + 1} : ${orderId}`);
}
// #1 : A-1001
// #2 : A-1002
// #3 : A-1003
| Réception | Contenu de la variable | Ligne affichée |
|---|---|---|
| Éléments via of | L'élément lui-même (A-1001) | En attente d'expédition : A-1001 |
| entries() en [index, orderId] | index : 0 / orderId : A-1001 | #1 : A-1001 |
| entries() dans une variable | La paire index-élément | Le tableau [0, "A-1001"] tel quel |
const [index, orderId] fonctionne comme la décomposition de tableaux vue dans l'article sur la déstructuration : l'index va à la première position, l'élément à la seconde. Une nouvelle variable est créée à chaque tour, tu peux donc déclarer la variable de boucle d'un for...of avec const sans provoquer d'erreur de réaffectation.
Parcourir les clés — for...in, et pourquoi l'éviter sur un tableau
Il arrive qu'on veuille afficher côte à côte le nom des clés et leurs valeurs, par exemple pour un profil de membre. Tu pourrais transformer les clés en tableau avec Object.keys(profile) puis le parcourir avec for...of, mais si tu veux seulement parcourir les clés, il existe une écriture plus courte.
for...in (une instruction qui parcourt une à une les clés d'un objet) s'écrit for (const key in profile). La variable contient la clé sous forme de chaîne, et non la valeur : tu lis donc la valeur avec la notation entre crochets, comme profile[key].
const profile = { displayName: "Léa", plan: "premium", posts: 12 };
// key contient la clé sous forme de chaîne (pas la valeur)
for (const key in profile) {
console.log(`${key}: ${profile[key]}`);
}
// displayName: Léa
// plan: premium
// posts: 12
// Sur un tableau, les index arrivent sous forme de chaînes
const stockCounts = [5, 0, 12];
for (const key in stockCounts) {
console.log(`${typeof key} / ${key + 1}`);
}
// string / 01
// string / 11
// string / 21 ← concaténés comme des chaînes, pas additionnés comme des nombres
Si tu ne fais que lire des éléments, comme avec stockCounts[key], la chaîne "1" te donne quand même la valeur. Tu pourrais la convertir avec Number(key) pour l'utiliser dans un calcul, mais pour les éléments d'un tableau, il est plus simple de choisir dès le départ une autre boucle. Le tableau ci-dessous indique quand utiliser chacune des trois.
| Syntaxe | Contenu de la variable | Idéal pour |
|---|---|---|
| for (let i = 0; i < count; i++) | L'index (nombre) | Utiliser la position dans un calcul |
| for (const item of array) | L'élément lui-même | Traiter les éléments dans l'ordre |
| for (const key in object) | La clé (chaîne) | Parcourir les clés d'un objet |
Impossible de parcourir un objet avec for...of
Si tu places un objet à droite de of, comme dans for (const item of profile), l'exécution s'arrête sur TypeError: profile is not iterable. Les objets simples ne sont pas itérables : ils ne définissent aucun moyen de livrer leur contenu un élément à la fois. Pour parcourir aussi les valeurs, transforme d'abord l'objet en tableau avec Object.entries.
Lister toutes les combinaisons — boucle interne et boucle externe
Tu veux maintenant lister les produits proposés par chaque magasin, sous forme de toutes les combinaisons magasin-produit. Une seule boucle peut parcourir soit les magasins, soit les produits, mais pas les deux à la fois. Et le nombre de magasins comme le nombre de produits dépendent des données.
Tu peux placer une autre boucle directement dans le corps d'une boucle. La boucle interne s'exécute entièrement à chaque tour de la boucle externe : le corps interne s'exécute donc le nombre de tours externes multiplié par le nombre de tours internes. La boucle interne peut aussi lire directement la variable de la boucle externe.
const stores = ["Shibuya", "Yokohama"];
const products = ["Mug", "Carnet"];
// À chaque tour de la boucle externe, la boucle interne s'exécute entièrement
for (const store of stores) {
for (const product of products) {
console.log(`${store} / ${product}`);
}
}
// Shibuya / Mug
// Shibuya / Carnet
// Yokohama / Mug
// Yokohama / Carnet
store— passe de "Shibuya" à "Yokohama" à chaque tour- Le corps externe ne s'exécute que 2 fois
product— passe de "Mug" à "Carnet" à chaque tour interne- Peut lire directement le
storeexterne - Ce corps s'exécute 2 × 2 = 4 fois
product, de la boucle interne, et store, de la boucle externe. product, déclarée dans la boucle interne, n'est utilisable qu'entre les accolades internes.Le for...of interne repart du début de products chaque fois que le tour externe change : tant que store reste le même, seul product change. Une variable déclarée au début du corps externe est elle aussi recréée à chaque tour externe. La façon dont les accolades limitent l'endroit où une variable est utilisable est traitée dans l'article sur la portée.
Vérification des connaissances
Répondez à chaque question une par une.
Question 2Quand tu parcours un tableau avec for...in, que contient la variable de boucle ?
Question 3Si tu parcours un tableau de 3 éléments et un tableau de 4 éléments dans une boucle imbriquée, combien de fois le corps interne s'exécute-t-il ?