Cette page a été traduite à partir de l'anglais par la communauté.Vous pouvez contribuer en rejoignant la communauté francophone sur MDN Web Docs.
for...of
Baseline Widely available
Cette fonctionnalité est bien établie et fonctionne sur de nombreux appareils et versions de navigateurs. Elle est disponible sur tous les navigateurs depuis juillet 2015.
L'instructionfor...of permet de créer une boucleArray qui parcourt unobjet itérable (ce qui inclut les objetsArray,Map,Set,String,TypedArray, l'objetarguments, etc.) et qui permet d'exécuter une ou plusieurs instructions pour la valeur de chaque propriété.
Dans cet article
Exemple interactif
const array1 = ["a", "b", "c"];for (const element of array1) { console.log(element);}// Expected output: "a"// Expected output: "b"// Expected output: "c"Syntaxe
for (variable of iterable) { instruction;}variableÀ chaque itération, la valeur d'une propriété différente est affectée à
variable(cette variable peut être déclarée avecconst,letouvar).iterableL'objet dont on parcourt les propriétés énumérables.
instructionUne instruction à exécuter pour chaque propriété, cette instruction peut être composée de plusieurs instructions en utilisant unbloc d'instructions.
Exemples
>Utiliserfor...of sur un tableau
let tableauItérable = [1, 2, 3];for (let valeur of tableauItérable) { console.log(valeur);}// 1// 2// 3Si la variable n'est pas réaffectée dans la boucle, on pourra également utiliserconst à la place delet :
let tableauItérable = [1, 2, 3];for (const valeur of tableauItérable) { console.log(valeur);}// 1// 2// 3Parcourir une chaîne de caractères avecfor...of
let iterable = "pixel";for (let valeur of iterable) { console.log(valeur);}// p// i// x// e// lParcourir un tableau typé (TypedArray)
let iterable = new Uint8Array([0x00, 0xff]);for (let valeur of iterable) { console.log(valeur);}// 0// 255Parcourir uneMap
let iterable = new Map([ ["a", 1], ["b", 2], ["c", 3],]);for (let element of iterable) { console.log(element);}// ['a', 1]// ['b', 2]// ['c', 3]for (let [clef, valeur] of iterable) { console.log(valeur);}// 1// 2// 3UtiliserArray.prototype.forEach()
Pour obtenir les mêmes valeurs qu'avec une bouclefor...of, on peut utiliser la méthodeArray.prototype.forEach() :
let arr = [3, 5, 7];arr.toto = "coucou";arr.forEach(function (element, index) { console.log(element); // affiche "3", "5", "7" console.log(index); // affiche "0", "1", "2"});// ou avec Object.keys()Object.keys(arr).forEach(function (element, index) { console.log(arr[element]); // affiche "3", "5", "7", "coucou" console.log(arr[index]); // affiche "3", "5", "7", undefined});Parcourir l'objetarguments
Il est possible de parcourir l'objetarguments afin d'examiner l'ensemble des paramètres passés à la fonction :
(function () { for (let argument of arguments) { console.log(argument); }})(1, 2, 3);// 1// 2// 3Parcourir des collections DOM
Il est possible de parcourir des collections DOM telles queNodeList. Dans cet exemple, on ajoute une classeread aux paragraphes qui sont des descendants directs d'un article :
// Note : Cela ne fonctionnera que pour les plates-formes// qui implémentent NodeList.prototype[Symbol.iterator]let articleParagraphs = document.querySelectorAll("article > p");for (let paragraph of articleParagraphs) { paragraph.classList.add("read");}Clôturer les itérateurs
Dans les bouclesfor...of, on peut provoquer la fin de l'itérateur avecbreak,continue,throw, oureturn. Dans ces cas, l'itérateur est fermé.
function* toto() { yield 1; yield 2; yield 3;}for (let o of toto()) { console.log(o); break; // L'itérateur est fermé}Itérer sur les générateurs
Grâce à cette instruction, on peut également itérer sur lesgénérateurs :
function* fibonacci() { // une fonction génératrice let [prev, curr] = [0, 1]; while (true) { [prev, curr] = [curr, prev + curr]; yield curr; }}for (let n of fibonacci()) { console.log(n); // on arrête la séquence à 1000 if (n >= 1000) { break; }}Itérer sur les autres objets itérables
Il est aussi possible d'itérer sur un objet qui implémentele protocole itérable de façon explicite :
var iterable = { [Symbol.iterator]() { return { i: 0, next() { if (this.i < 3) { return { value: this.i++, done: false }; } return { value: undefined, done: true }; }, }; },};for (let value of iterable) { console.log(value);}console.log("fini !");// 0// 1// 2Les différences entrefor...of etfor...in
Les deux instructionsfor...in etfor...of permettent de parcourir un ensemble. Mais elles ne parcourent pas le même ensemble.
L'instructionfor...in permet de parcourirles propriétés énumérables d'un objet dans un ordre arbitraire.
L'instructionfor...of permet quant à elle de parcourir les données contenues dans l'objet itérable visé.
Dans l'exemple qui suit, on illustre la différence de comportement entre une bouclefor...of et une bouclefor...in utilisées sur un tableau (Array).
Object.prototype.objCustom = function () {};Array.prototype.arrCustom = function () {};let iterable = [3, 5, 7];iterable.toto = "coucou";for (let i in iterable) { console.log(i); // affiche 0, 1, 2, "toto", // "arrCustom", "objCustom"}for (let i in iterable) { if (iterable.hasOwnProperty(i)) { console.log(i); // affiche 0, 1, 2, "toto" }}for (let i of iterable) { console.log(i); // affiche 3, 5, 7}Chaque objet héritera de la propriétéobjCustom et chaque objet qui est un tableau (Array) héritera de la propriétéarrCustom car on les ajoute aux prototypesObject.prototype etArray.prototype. L'objetiterable hérite donc des propriétésobjCustom etarrCustom grâceà l'héritage et à la chaîne de prototypes.
for (let i in iterable) { console.log(i); // affiche 0, 1, 2, "toto", // "arrCustom" et "objCustom"}Cette boucle ne parcourt que lespropriétés énumérables de l'objetiterable dans un ordre arbitraire. Les éléments du tableau3,5,7 ouhello ne sont pas affichés car ce ne sont pas des propriétés (et encore moins des propriétés énumérables). En revanche, on retrouve bien les indices du tableau et les propriétésarrCustom etobjCustom. Pour décrire plus précisément ce comportement, vous pouvez consulterfor...in.
for (let i in iterable) { if (iterable.hasOwnProperty(i)) { console.log(i); // affiche 0, 1, 2, "toto" }}Cette boucle ressemble à la première mais ajoute la méthodehasOwnProperty() qui permet de vérifier si la propriété énumérable recensée est directement disponible sur l'objet (c'est-à-dire si elle n'est pas héritée). La console affiche donc les propriétés0,1,2 ettoto car ce sont des propriétés directement rattachées à l'objetiterable. En revanche, les propriétésarrCustom etobjCustom ne sont pas affichées car elles proviennent de l'héritage.
for (let i of iterable) { console.log(i); // affiche 3, 5, 7}Cette boucle parcourt les valeurs définies comme itérables parl'objet itérable et dans ce cas ce sont les éléments du tableau3,5,7 et pas les propriétés de l'objet.
Attention à ne pas réutiliser les générateurs
Les générateurs ne doivent pas être réutilisés, même lorsque la bouclefor...of a été interrompue (par exemple lorsquebreak est utilisé). Lorsqu'on quitte une boucle, le générateur est clôturé et si on l'utilise à nouveau, il ne fournira aucun résultat. Firefox n'a pas encore implémenté ce comportement standard (cf.bug Firefox 1147371).
var gen = (function* () { yield 1; yield 2; yield 3;})();for (let o of gen) { console.log(o); break; // L'itérateur est fermé}// Le générateur ne doit pas être réutilisé !for (let o of gen) { console.log(o); // Ceci n'est jamais exécuté}Spécifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # sec-for-in-and-for-of-statements> |