Movatterモバイル変換


[0]ホーム

URL:


  1. Web
  2. JavaScript
  3. Guide JavaScript
  4. Itérateurs et générateurs

Cette page a été traduite à partir de l'anglais par la communauté.Vous pouvez contribuer en rejoignant la communauté francophone sur MDN Web Docs.

View in EnglishAlways switch to English

Itérateurs et générateurs

Effectuer des traitements sur chacun des éléments d'une collection est une opération très fréquente. Il existe plusieurs outils natifs dans JavaScript pour parcourir une collection, les bouclesfor,map(),filter(). Les itérateurs et les générateurs font de ce concept d'itération une fonctionnalité principale du langage et permettent d'adapter et de personnaliser le comportement des bouclesfor...of.

Pour plus de détails sur les mécanismes d'itération, voir les pages suivantes :

Itérateurs

Un itérateur est un objet sachant comment accéder aux éléments d'une collection un par un et qui connait leur position dans la collection. En JavaScript, un itérateur expose une méthodenext() qui retourne l'élément suivant dans la séquence. Cette méthode renvoie un objet possédant deux propriétés :done etvalue.

Un itérateur est "terminé" lorsque l'appel à la méthodenext() renvoie un objet dont la propriétédone vauttrue.

Une fois créé, un itérateur peut être utilisé explicitement en appelant sa méthodenext(), ou implicitement en utilisant la bouclefor...in.

Voici un exemple d'une fonction créant un itérateur qui parcourt l'intervalle défini par ses arguments (depuisdebut (inclus) jusqu'àend (exclus) et avecpas comme incrément. La valeur finale qui est renvoyée correspond à la taille de la séquence créée

js
function creerIterateurIntervalle(debut = 0, fin = Infinity, pas = 1) {  let prochainIndex = debut;  let nbIterations = 0;  const rangeIterator = {    next: function () {      let resultat;      if (prochainIndex < fin) {        resultat = { value: prochainIndex, done: false };        prochainIndex += pas;        nbIterations++;        return resultat;      }      return { value: nbIterations, done: true };    },  };  return rangeIterator;}

On pourra alors utiliser cette fonction et l'itérateur de la façon suivante :

js
let it = creerIterateurIntervalle(1, 10, 2);let resultat = it.next();while (!resultat.done) {  console.log(resultat.value); // 1 3 5 7 9  resultat = it.next();}console.log("La séquence parcourue contenait ", result.value, " éléments.");

Itérables

Un objet est considéré commeitérable s'il définit le comportement qu'il aura lors de l'itération (par exemple les valeurs qui seront utilisées dans une bouclefor...of). Certains types natifs, tels qu'Array ouMap, possède un comportement par défaut pour les itérations, cependant d'autres types comme les Objets, ne possèdent pas ce comportement.

Pour qu'un objet soititérable, un objet doit implémenter la méthode@@iterator, cela signifie que l'objet (ou un des objets de lachaîne de prototypes) doit avoir une propriété avec la cléSymbol.iterator. Cette fonction doit également, même si ce n'est pas une obligation, renvoyer une nouvel opérateur à chaque appel.

Itérables personnalisés

Il est possible de définir ses propres itérables de cette façon :

js
var monItérable = {};monItérable[Symbol.iterator] = function* () {  yield 1;  yield 2;  yield 3;};[...monItérable]; // [1, 2, 3]

Itérables natifs

String,Array,TypedArray,Map etSet sont des itérables natifs car les prototypes de chacun ont tous une méthodeSymbol.iterator.

Les éléments de syntaxe utilisant des itérables

Certaines instructions ou expressions utilisent des itérables, par exemple les bouclesfor...of etyield*.

js
for (let value of ["a", "b", "c"]) {  console.log(value);}// "a"// "b"// "c"[..."abc"]; // ["a", "b", "c"]function* gen() {  yield* ["a", "b", "c"];}gen().next()[(a, b, c)] = // { value:"a", done:false }  new Set(["a", "b", "c"]);a; // "a"

Générateurs

Les itérateurs personnalisés sont un outil utile mais leur création peut s'avérer complexe et il faut maintenir leur état interne. Avec les générateurs, on peut définir une seule fonction qui est un algorithme itératif et qui peut maintenir son état.

Un générateur est un type de fonction spécial qui fonctionne comme une fabrique (factory) d'itérateurs. Une fonction devient un générateur lorsqu'elle contient une ou plusieurs expressionsyield et qu'elle utilise la syntaxefunction*.

js
function* idMaker() {  var index = 0;  while (true) yield index++;}var gen = idMaker();console.log(gen.next().value); // 0console.log(gen.next().value); // 1console.log(gen.next().value); // 2// ...

Générateurs avancés

Les générateurs calculent les valeurs à fournir à la demande, ce qui leur permet de représenter efficacement des suites complexes à calculer, voire des séries infinies (comme vu dans l'exemple précédent).

La méthodenext() accepte également un argument qui pourra être utilisé pour modifier l'état interne du générateur. Une valeur passée ànext() sera traitée comme le résultat de la dernière expressionyield qui a interrompu le générateur. Une valeur passée au premier appel denext() sera toujours ignorée.

Par exemple, on peut avoir un générateur pour la suite de Fibonnaci et utilisernext(x) pour redémarrer la série :

js
function* fibonacci() {  var fn1 = 0;  var fn2 = 1;  while (true) {    var current = fn1;    fn1 = fn2;    fn2 = fn1 + current;    var reset = yield current;    if (reset) {      fn1 = 0;      fn2 = 1;    }  }}var sequence = fibonacci();console.log(sequence.next().value); // 0console.log(sequence.next().value); // 1console.log(sequence.next().value); // 1console.log(sequence.next().value); // 2console.log(sequence.next().value); // 3console.log(sequence.next().value); // 5console.log(sequence.next().value); // 8console.log(sequence.next(true).value); // 0console.log(sequence.next().value); // 1console.log(sequence.next().value); // 1console.log(sequence.next().value); // 2

Il est possible de forcer un générateur à lever une exception en utilisant la méthodethrow() en lui passant la valeur de l'exception en argument. Cette exception sera levée depuis l'état actuel du générateur, comme si leyield qui était en attente avait été une instructionthrow valeur.

Si le mot-cléyield n'est pas trouvé lors de la levée de l'exception, l'exception sera propagée jusqu'à l'appel dethrow(), les appels ànext() qui suivent renverront une valeur dont la propriétédone seratrue.

Si l'exception n'est pas interceptée dans le générateur, elle se propagera jusqu'à l'appel dethrow() et les appels suivants denext() renverront un objet dont la propriétédone vauttrue.

Les générateurs possèdent une méthodereturn(valeur) qui permet de renvoyer une valeur donnée et de terminer le générateur.

Help improve MDN

Learn how to contribute

Cette page a été modifiée le par lescontributeurs du MDN.


[8]ページ先頭

©2009-2025 Movatter.jp