In JavaScript un iteratore è un oggetto che definisce una sequenza e potenzialmente un valore di ritorno al suo termine.
In particolare, un iteratore è qualsiasi oggetto che implementa il protocollo Iteratore avendo unnext()
metodo che restituisce un oggetto con due proprietà:
value
Il valore successivo nella sequenza di iterazione. done
Questo è true
se l’ultimo valore nella sequenza è già stato consumato. Sevalue
è presente insieme adone
, è il valore restituito dall’iteratore.
Una volta creato, un oggetto iteratore può essere iterato esplicitamente chiamando ripetutamente next()
. Si dice che l’iterazione su un iteratore consumi l’iteratore, perché in genere è possibile farlo solo una volta. Dopo che un valore di terminazione è stato restituito, ulteriori chiamate a next()
dovrebbero continuare a restituire {done: true}
.
L’iteratore più comune in JavaScript è l’iteratore dell’array, che restituisce ogni valore nell’array associato in sequenza.
Mentre è facile immaginare che tutti gli iteratori possano essere espressi come array, questo non è vero. Gli array devono essere allocati nella loro interezza, ma gli iteratori vengono consumati solo se necessario. Per questo motivo, gli iteratori possono esprimere sequenze di dimensioni illimitate, come l’intervallo di numeri interi tra 0
e Infinity
.
Ecco un esempio che può fare proprio questo. Consente la creazione di un semplice iteratore di intervalli che definisce una sequenza di numeri interi da start
(incluso) a end
(esclusivo) distanziati step
a parte. Il suo valore finale di ritorno è la dimensione della sequenza creata, tracciata dalla variabile iterationCount
.
function makeRangeIterator(start = 0, end = Infinity, step = 1) { let nextIndex = start; let iterationCount = 0; const rangeIterator = { next: function() { let result; if (nextIndex < end) { result = { value: nextIndex, done: false } nextIndex += step; iterationCount++; return result; } return { value: iterationCount, done: true } } }; return rangeIterator;}
L’uso dell’iteratore è simile a questo:
const it = makeRangeIterator(1, 10, 2);let result = it.next();while (!result.done) { console.log(result.value); // 1 3 5 7 9 result = it.next();}console.log("Iterated over sequence of size: ", result.value); //
Nota: non è possibile sapere in modo riflessivo se un particolare oggetto è un iteratore. Se hai bisogno di farlo, usa Iterables.