Deux boucles, deux rôles bien distincts
JavaScript propose deux formes de boucles qui se ressemblent comme deux gouttes d'eau, mais qui ne font pas du tout la même chose. La boucle for...of parcourt les valeurs d'un itérable, tandis que la boucle for...in parcourt les clés d'un objet. Une seule lettre d'écart, mais un comportement radicalement différent.
Voici toute l'histoire résumée en un seul exemple :
La première boucle affiche apple, banana, cherry — les valeurs. La seconde affiche 0, 1, 2 — les clés, sous forme de chaînes. Si tu te trompes de boucle, tu vas passer dix minutes à te demander pourquoi ton tableau est rempli de nombres.
for...of : parcourir les valeurs de tout ce qui est itérable
La boucle for...of en JavaScript, c'est celle que tu vas utiliser le plus souvent. Elle fonctionne sur tout ce que JavaScript considère comme itérable : tableaux, chaînes de caractères, Map, Set, NodeList, générateurs, et bien d'autres.
Fini la gymnastique avec les indices, terminé le scores[i]. Tu demandes chaque valeur, tu récupères chaque valeur. Les chaînes sont également itérables — for...of les parcourt caractère par caractère :
Ça fonctionne aussi correctement avec la plupart des points de code Unicode, ce qui est un petit avantage bien réel par rapport à l'accès à une chaîne via un index numérique.
Récupérer l'index dans une boucle for...of
La seule chose que for...of ne te donne pas directement, c'est la position. Quand tu en as besoin, combine la boucle avec entries() :
names.entries() renvoie des paires [index, value], et le déstructuring juste avant permet de les séparer dans deux variables distinctes. C'est souvent plus propre que de retomber sur un bon vieux for (let i = 0; ...) uniquement parce qu'on a besoin de i.
for...in : parcourir les clés d'un objet
La boucle for...in est faite pour les objets classiques. Elle itère sur les clés énumérables de type string :
Attention : tu récupères la clé, pas la valeur. Pour lire la valeur, il faut réinterroger l'objet avec user[key]. Et chaque clé est une chaîne de caractères — même quand elle ressemble à un nombre.
for...in remonte aussi la chaîne de prototypes, ce qui peut faire apparaître des propriétés héritées. Sur tes propres objets littéraux, ça pose rarement problème, mais dès que tu itères sur des instances de classe ou sur des objets venus d'une bibliothèque, mieux vaut prévoir le coup :
Object.hasOwn(user, key) ignore tout ce qui vient de l'héritage. Dans le code moderne, la plupart des devs évitent carrément for...in et utilisent plutôt Object.keys, Object.values ou Object.entries — ce qui nous amène à la section suivante.
La façon moderne d'itérer un objet JavaScript
Au lieu de for...in, on combine for...of avec l'un des helpers Object.*. À toi de choisir celui des trois qui colle à ton besoin :
Object.entries est particulièrement agréable : en déstructurant la paire [key, value], la lecture devient quasi naturelle. Et comme ces méthodes ne renvoient que les propriétés propres et énumérables de l'objet, pas besoin de se soucier des propriétés héritées parasites.
À éviter : for...in sur un tableau
Techniquement, c'est autorisé, mais c'est une source de pièges classiques :
Tu récupères 0, 1, 2, et aussi tag. Toute propriété qu'on aurait collée sur le tableau — ou sur Array.prototype via un polyfill — apparaît également. Les clés sont des chaînes, donc key + 1 fait une concaténation au lieu d'une addition. Et l'ordre d'itération n'est pas garanti de correspondre à celui du tableau dans tous les cas limites.
Règles pratiques :
- Besoin des valeurs d'un tableau ?
for...of arr. - Index et valeur d'un tableau ?
for...of arr.entries(). - Uniquement l'index, avec un compteur ? La boucle classique
for (let i = 0; i < arr.length; i++). - Clés ou paires clé/valeur d'un objet ?
Object.keys(obj)/Object.entries(obj)combinés avecfor...of.
En résumé : for...in reste un outil de niche. La combinaison for...of + les méthodes de Object couvre tout ce dont tu as besoin.
break et continue fonctionnent dans les deux
Les deux boucles acceptent les instructions classiques pour sortir plus tôt :
continue passe à l'itération suivante ; break sort complètement de la boucle. C'est la raison principale de préférer for...of à .forEach() — dans un forEach, la fonction callback ne peut pas break pour sortir de la boucle, alors qu'un for...of le permet sans problème.
Récapitulatif côte à côte
Quatre boucles, quatre usages, une seule logique à garder en tête : si tu veux récupérer les valeurs d'un itérable, utilise for...of. Si tu veux manipuler les propriétés d'un objet, passe par Object.keys / Object.values / Object.entries, toujours avec for...of. Garde for...in pour les rares cas où tu veux vraiment toutes les clés énumérables d'un objet, héritées ou non.
La suite : truthy et falsy
Chaque boucle et chaque if en JavaScript finit par poser la même question : est-ce que cette valeur est considérée comme vraie ? Et la réponse n'est pas toujours évidente — les chaînes vides, zéro, null et undefined ne se comportent pas forcément comme tu l'imagines. On passe aux valeurs truthy et falsy juste après.
Questions fréquentes
Quelle est la différence entre for...of et for...in en JavaScript ?
for...of parcourt les valeurs d'un itérable : tableau, chaîne de caractères, Map ou Set. for...in, lui, parcourt les clés (les noms de propriétés) d'un objet. Sur un tableau ['a', 'b'], for...of te donne 'a' puis 'b', alors que for...in renvoie '0' et '1'… sous forme de chaînes.
Est-ce qu'on peut utiliser for...of sur un objet ?
Pas directement : un objet classique n'est pas itérable. Il faut passer par Object.keys(obj), Object.values(obj) ou Object.entries(obj) pour récupérer un tableau que tu pourras parcourir avec for...of. Le pattern qu'on voit partout, c'est for (const [key, value] of Object.entries(obj)).
Pourquoi éviter for...in sur un tableau ?
Techniquement ça marche, mais for...in parcourt toutes les propriétés énumérables, y compris celles héritées ou ajoutées à Array.prototype par une lib tierce. En plus, les clés sont retournées sous forme de chaînes et l'ordre n'est pas toujours garanti. Pour les valeurs, utilise for...of ; si tu as besoin de l'index, une boucle for classique fait très bien le job.