Iterables en JavaScript

Le protocole des itérations permet aux objets JavaScript de définir et de personnaliser leur comportement d'itération, comme les valeurs sur lesquelles sont effectuées les boucles dans for...of.

Les tableaux sont considérés comme itérables. Cependant, il existe également d'autres itérables (par exemple, les chaînes).

Description de Symbol.iterator

Essayons de créer un itérable.

Par exemple, il existe un objet qui n'est pas un tableau mais qui peut être adapté pour for...of.

Voyons un exemple d'un objet de plage, représentant un intervalle de nombres:

let range = {
  from: 0,
  to: 10
}; 
// We want the for..of to work:
// for(let num of range) ... num=0,1,2,3,4,5,6,7,8,9,10

Pour transformer la plage en itérable, il est nécessaire d'ajouter une méthode à l'objet appelée Symbol.iterator.

Voici les étapes:

  1. Une fois que for..of commence, la méthode est appelée une fois. Elle doit renvoyer un itérateur.
  2. Ensuite, for..of peut fonctionner avec l'objet renvoyé.
  3. Une fois que for..of attend la valeur suivante, next() est appelé sur cet objet.
  4. Son résultat doit inclure la forme {done: Boolean, value: any}.

La performance complète pour la plage avec des remarques ressemblera à ceci:

Javascript range object call Symbol.iterator
let range = { from: 0, to: 5 }; // 1. called to for..of initially calls this range[Symbol.iterator] = function () { //returns an iterator object: // 2.for..of works only with this iterator, querying it for next values return { currentValue: this.from, lastValue: this.to, // 3. next() is called at each iteration with a for..of loop next() { // 4. it should return the value as an object {done:.., value :...} if (this.currentValue <= this.lastValue) { return { done: false, value: this.currentValue++ }; } else { return { done: true }; } } }; }; for (let num of range) { console.log(num); // 0, then 1, 2, 3, 4, 5 }

La caractéristique la plus essentielle des itérables est la séparation des préoccupations. Il considère que l'objet itérateur est distinct de ceux sur lesquels il itère. Il est possible de les fusionner en utilisant la plage comme un itérateur pour simplifier le code, comme le montre l'exemple ci-dessous:

Javascript range object call Symbol.iterator
let range = { from: 0, to: 5, [Symbol.iterator]() { this.currentValue = this.from; return this; }, next() { if (this.currentValue <= this.to) { return { done: false, value: this.currentValue++ }; } else { return { done: true }; } } }; for (let num of range) { console.log(num); // 0, then 1, 2, 3, 4, 5 }

Le principal inconvénient de ce cas est qu'il n'est pas possible d'avoir deux for..of qui s'exécutent sur l'objet en même temps.

Il peut y avoir des itérateurs infinis. Par exemple, vous pouvez transformer une plage en infinie avec range.to = Infinity. Il existe également une autre option: vous pouvez créer un objet itérable qui génère une séquence infinie de nombres pseudo-aléatoires. Ainsi, aucune limitation n'est appliquée sur next, et il peut renvoyer plus de valeurs. En conséquence, la boucle for..of deviendra également sans fin sur un itérable comme celui-ci. Mais elle peut être arrêtée avec break.

Les chaînes comme itérables

Les itérables les plus couramment utilisés sont les chaînes et les tableaux.

Le for..of peut parcourir ses caractères, dans le cas d'une chaîne:

Javascript strings iterables
for (let char of "W3Docs") { // triggers 6 times: once for each character console.log(char); // W, then 3, then D, then o, then c, then s }

Il fonctionnera correctement, comme ceci:

Javascript strings iterables
let str = 'ȬẂ'; for (let char of str) { console.log(char); // Ȭ, and then Ẃ }

Objects semblables à des tableaux et itérables

Dans ce paragraphe, nous passerons en revue les termes itérables et objets semblables à des tableaux. Ils peuvent sembler similaires mais sont très différents.

Les objets semblables à des tableaux sont des objets qui contiennent des index et une length. Les itérables sont des objets capables de mettre en œuvre la méthode Symbol.iterator. Cette méthode a été décrite ci-dessus.

En utilisant JavaScript, vous pouvez rencontrer beaucoup d'objets qui sont semblables à des tableaux et itérables. Par exemple, les chaînes peuvent être à la fois itérables et semblables à des tableaux. Par contre, un itérable ne peut jamais devenir un objet qui ressemble à un tableau, et vice versa.

Voyons un exemple d'un objet qui ressemble à un tableau mais qui n'est pas un itérable:

Javascript object is an array-like not an iterable
let arrLike = { // has indexes and length => array-like 0: "Welcome", 1: "to", 2: "W3Docs", length: 3 }; // Error (no Symbol.iterator) for (let item of arrLike) { console.log(item); }

En général, les itérables et les objets semblables à des tableaux ne sont pas des tableaux, car ils ne contiennent pas de pop, de push, etc.

Description de Array-form

Array-form est une méthode générique utilisée pour prendre une valeur itérable ou semblable à un tableau et en faire un vrai tableau. Ensuite, les méthodes de tableau peuvent être appelées dessus. Voici un exemple d'utilisation de array-form:

Javascript object is an array-like iterable
let arrLike = { 0: "Welcome", 1: "to", 2: "W3Docs", length: 3 }; let arr = Array.from(arrLike); // (*) console.log(arr.pop()); // W3Docs (method operates)

Au niveau de la ligne (*), Array.from accepte l'objet, examine s'il s'agit d'un objet semblable à un tableau ou d'un itérable, puis crée un nouveau tableau, copiant tous les éléments dedans. Voyons comment cela se passe avec un itérable:

Javascript array an iterable
let range = { from: 0, to: 5, [Symbol.iterator]() { this.currentValue = this.from; return this; }, next() { if (this.currentValue <= this.to) { return { done: false, value: this.currentValue++ }; } else { return { done: true }; } } }; //confirming that the range is obtained from the above example let arr = Array.from(range); console.log(arr); // 0,1,2,3,4,5 ;array toString conversion works

La syntaxe complète de Array.from ressemble à ceci:

Array.from(obj[, mapFunc, thisArg])

Le deuxième argument mapFn est une fonction, qui peut être attachée à chaque élément avant de l'ajouter au tableau. Le troisième argument thisArg permet de définir this pour cela. Voici un exemple:

Javascript object is an array-like not an iterable
let range = { from: 0, to: 5, [Symbol.iterator]() { this.currentValue = this.from; return this; }, next() { if (this.currentValue <= this.to) { return { done: false, value: this.currentValue++ }; } else { return { done: true }; } } }; // provided that the range is taken from the above example // square of each number let arr = Array.from(range, num => num * num); console.log(arr); // 0,1,4,9,16,25

Maintenant, transformons une chaîne en un tableau de caractères avec l'aide de Array.from:

Javascript turn a string into an array of characters
let str = 'ȬẂ'; // splits the str into an array of characters let chars = Array.from(str); console.log(chars[0]); // Ȭ console.log(chars[1]); // Ẃ console.log(chars.length); // 2

Contrairement à la méthode str.split, cela dépend de la nature itérable de la chaîne.

Cela fonctionne de la même manière que:

Javascript turn a string into an array of characters
let str = 'ȬẂ'; let charsArr = []; // Array.from internally does the same loop for (let char of str) { charsArr.push(char); } console.log(charsArr);

Résumé

Les itérables sont des objets qui peuvent être utilisés dans le for..of.

En général, ils doivent effectuer la méthode Symbol.iterator. Cette méthode est généralement appelée automatiquement par for..of. Mais, elle peut également être appelée directement. Les objets ayant des propriétés indexées et une length sont considérés comme des objets semblables à des tableaux. Ils peuvent également inclure d'autres propriétés et méthodes, mais ils ne sont pas de véritables tableaux. Pour les transformer en tableaux, vous pouvez utiliser la méthode Array.from(obj[, mapFn, thisArg]).

Les arguments mapFn et thisArg permettent d'appliquer une fonction à chacun d'eux.

Heure du Quiz : Testez Vos Compétences!

Prêt à relever le défi de ce que vous avez appris ? Plongez dans nos quiz interactifs pour approfondir votre compréhension et renforcer vos connaissances de manière ludique.

Trouvez-vous cela utile?