Iterators in Javascript

Muhammad Hassan
3 min readMay 6, 2021

Iterators

In JavaScript, an iterator is an object which defines a sequence and potentially a return value upon its termination.

An iterator can be any object that implements the Iterator interface. This means that it needs to have a next() method that returns an object with two properties:

  • value: the next value in the sequence.
  • done: this value is true if the last value in the sequence has been consumed. If the value property is also present, it’s the iterator’s return value.

Once created, an iterator object can be iterated by invoking the next() method. After the last value in the sequence has been reached, additional calls to next() should continue returning {done: true}.

What are Iterables and Iterators?

ES6 introduces a new mechanism for traversing data: iteration. Two concepts are central to iteration:

  • An iterable is a data structure that wants to make its elements accessible to the public. It does so by implementing a method whose key is Symbol.iterator. That method is a factory for iterators.
  • An iterator is a pointer for traversing the elements of a data structure (think cursors in databases)

Iterable values in Javascript

The following values are iterable:

  • Arrays
  • Strings
  • Maps
  • Sets
  • DOM data structures (work in progress)

Plain objects are not iterable.

The idea of iterability is as follows.

  • Data consumers: JavaScript has language constructs that consume data. For example, for-of loops over values and the spread operator (...) inserts values into Arrays or function calls.
  • Data sources: The data consumers could get their values from a variety of sources. For example, you may want to iterate over the elements of an Array, the key-value entries in a Map or the characters of a string.

Using Iterators

Sometimes it might require too many resources in order to allocate an array with values and loop through each of them. Iterators, on the other hand, are consumed only as necessary. This gives the potential of iterators to even express sequences of unlimited size.

Here is an example that shows the creation of a simple iterator that generates the Fibonacci Sequence:

function makeFibonacciSequenceIterator(endIndex = Infinity) {
let currentIndex = 0;
let previousNumber = 0;
let currentNumber = 1;

return {
next: () => {
if (currentIndex >= endIndex) {
return { value: currentNumber, done: true };
}

let result = { value: currentNumber, done: false };
let nextNumber = currentNumber + previousNumber;
previousNumber = currentNumber;
currentNumber = nextNumber;
currentIndex++;

return result;
}
};

The makeFibonacciSequenceIterator simply starts generating the Fibonacci numbers and stops when it reaches the endIndex. The iterator returns the current Fibonacci number on each iteration and continues returning the last generated number upon completion.

This is how the Fibonacci numbers can be generated through the iterator above:

let fibonacciSequenceIterator = makeFibonacciSequenceIterator(5); 
// Generates the first 5 numbers.
let result = fibonacciSequenceIterator.next();while (!result.done) {
console.log(result.value); // 1 1 2 3 5 8
result = fibonacciSequenceIterator.next();
}

The following ES6 language constructs make use of the Iterable:

  • Destructuring via an Array pattern
  • for-of loop
  • Array.from()
  • Spread operator (...)
  • Constructors of Maps and Sets
  • Promise.all(), Promise.race()
  • yield*

Resources:

--

--