la programmation

Itérateurs vs Générateurs en JavaScript

En JavaScript, les itérateurs (ou « iterators » en anglais) et les générateurs (ou « generators » en anglais) sont des fonctionnalités essentielles pour gérer les séquences de données et les itérations de manière efficace et flexible. Bien que leur objectif soit similaire, ils diffèrent dans leur implémentation et leur utilisation.

Commençons par les itérateurs. Un itérateur est un objet qui fournit une interface pour itérer sur une collection de données, telle qu’un tableau ou un ensemble. Il expose une méthode next() qui renvoie l’élément suivant de la collection à chaque appel, ainsi qu’une propriété done qui indique si l’itération est terminée. Les itérateurs sont largement utilisés avec les boucles for...of pour parcourir les éléments d’une collection de manière séquentielle et cohérente.

Par exemple, considérons un tableau JavaScript :

javascript
let monTableau = [1, 2, 3, 4, 5];

Pour créer un itérateur pour ce tableau, vous pouvez utiliser la méthode values() :

javascript
let monIterateur = monTableau.values();

Maintenant, vous pouvez itérer sur les éléments du tableau en utilisant une boucle for...of :

javascript
for (let element of monIterateur) { console.log(element); }

Cette boucle parcourra chaque élément du tableau et affichera sa valeur.

Maintenant, passons aux générateurs. Les générateurs sont des fonctions spéciales qui peuvent être interrompues et reprises pendant leur exécution. Ils produisent une séquence de valeurs sur demande, ce qui les rend utiles pour générer des séquences potentiellement infinies ou coûteuses en ressources de manière paresseuse.

Pour déclarer un générateur en JavaScript, vous utilisez la syntaxe function* :

javascript
function* monGenerateur() { yield 1; yield 2; yield 3; yield 4; yield 5; }

Chaque fois que la fonction next() du générateur est appelée, elle reprend son exécution à partir du point où elle a été interrompue par la dernière instruction yield, et renvoie un objet contenant la valeur fournie par yield ainsi que l’indicateur done indiquant si le générateur a terminé sa séquence.

Voici comment vous pouvez utiliser un générateur :

javascript
let monGenerateurInstance = monGenerateur(); console.log(monGenerateurInstance.next().value); // Affiche 1 console.log(monGenerateurInstance.next().value); // Affiche 2 console.log(monGenerateurInstance.next().value); // Affiche 3 console.log(monGenerateurInstance.next().value); // Affiche 4 console.log(monGenerateurInstance.next().value); // Affiche 5 console.log(monGenerateurInstance.next().value); // Affiche undefined (la séquence est terminée)

Un aspect important des générateurs est leur capacité à gérer les boucles infinies de manière efficace en ne générant que les valeurs nécessaires à la demande.

En résumé, les itérateurs fournissent une interface pour itérer de manière synchronisée sur des collections de données existantes, tandis que les générateurs permettent de créer des séquences de valeurs de manière paresseuse et potentiellement infinie. Chacun de ces mécanismes offre des avantages distincts en fonction des besoins spécifiques de programmation.

Plus de connaissances

Bien sûr, explorons plus en détail les itérateurs et les générateurs en JavaScript.

Itérateurs :

Les itérateurs sont des objets qui implémentent une méthode next() qui renvoie l’élément suivant dans la séquence et une propriété done qui indique si l’itération est terminée. Ils sont largement utilisés avec les boucles for...of pour parcourir des séquences de données telles que les tableaux, les ensembles, les chaînes de caractères, etc.

En JavaScript, de nombreux types de données intégrés, tels que les tableaux (Array), les ensembles (Set) et les cartes (Map), exposent des itérateurs via des méthodes telles que values(), keys() et entries().

Par exemple, pour créer un itérateur pour un tableau, vous pouvez utiliser values() :

javascript
let monTableau = [1, 2, 3]; let monIterateur = monTableau.values(); console.log(monIterateur.next()); // Affiche { value: 1, done: false } console.log(monIterateur.next()); // Affiche { value: 2, done: false } console.log(monIterateur.next()); // Affiche { value: 3, done: false } console.log(monIterateur.next()); // Affiche { value: undefined, done: true }

Vous pouvez également créer vos propres itérateurs en définissant une méthode Symbol.iterator sur votre objet. Cette méthode doit renvoyer un objet avec une méthode next().

Générateurs :

Les générateurs sont des fonctions spéciales qui peuvent être interrompues et reprises pendant leur exécution. Ils produisent une séquence de valeurs sur demande à l’aide de l’instruction yield. Les générateurs sont déclarés avec la syntaxe function* et peuvent contenir plusieurs instructions yield.

Par exemple, voici un générateur simple qui génère les nombres de 1 à n :

javascript
function* genererNombres(n) { for (let i = 1; i <= n; i++) { yield i; } } let monGenerateur = genererNombres(3); console.log(monGenerateur.next()); // Affiche { value: 1, done: false } console.log(monGenerateur.next()); // Affiche { value: 2, done: false } console.log(monGenerateur.next()); // Affiche { value: 3, done: false } console.log(monGenerateur.next()); // Affiche { value: undefined, done: true }

Un aspect puissant des générateurs est leur capacité à générer des séquences potentiellement infinies de manière paresseuse. Cela signifie que les valeurs ne sont calculées que lorsqu’elles sont demandées, ce qui peut économiser des ressources.

Comparaison :

  • Les itérateurs sont synchrones, ce qui signifie qu’ils fournissent les éléments de manière séquentielle et bloquent l’exécution du code jusqu’à ce que tous les éléments aient été itérés.
  • Les générateurs, en revanche, sont asynchrones et permettent une exécution interrompue, ce qui signifie que l’exécution du code peut être suspendue et reprise à tout moment.

Les générateurs offrent une syntaxe plus concise et plus expressive pour générer des séquences de valeurs, en particulier lorsque ces séquences sont potentiellement infinies ou coûteuses à calculer. Les itérateurs, en revanche, sont plus adaptés pour itérer sur des collections de données existantes de manière séquentielle et cohérente.

En résumé, les itérateurs et les générateurs sont des outils puissants en JavaScript pour travailler avec des séquences de données, offrant des approches complémentaires pour l’itération synchronisée et l’itération asynchrone.

Bouton retour en haut de la page