DEV Community

Thomas Barrasso
Thomas Barrasso

Posted on

Symbol.iterator for modular iteration without cloning or modifying in-place

Symbol.iterator is the protocol that makes native objects like Array, Set, and Map iterable. It provides a hook into language features like the spread operator and for…of loops.

With Symbol.iterator, developers can redefine navigation patterns without cloning or modifying an object in-place. That means iterating forwards, backwards, randomly, infinitely, pairwise, or just about any way you can imagine.

The protocol specification is very simple:

  • Iterable: the object with a function whose key is Symbol.iterator
  • Iterator: the iterable function, used to obtain the values to be iterated

These two properties tell the Javascript runtime what the next value is and when iteration is done.

Consider this example for iterating in reverse:

Instead of iterating backwards using indices or Array.reverse, we have defined the “going backwards” behavior for any array. We have done so while preserving the order and without creating a clone of the original array.

reverse can now be used in for...of loops or with the spread operator:

Symbol.iterator can also be used to recreate Python's range function.

Now we can elegantly iterate over a range of numbers without needing to create an intermediate array.

It even seems that performance is comparable to a standard for loop.

We do not even need to limit ourselves to a single collection. Like many libraries, we can write a zip function that combines multiple sequential collections of equal length, without needing to clone them in their entirety.

This allows us to seamlessly iterate pairwise (or triplet-wise):

In this case, Symbol.iterator significantly outperforms an cloning implementation using Array.map.

There are many uses for Symbol.iterator, and while it is more verbose than Array.map, it is more versatile and potentially more efficient.

Top comments (0)