codeburst

Bursts of code to power through your day. Web Development articles, tutorials, and news.

Follow publication

A Simple Guide to ES6 Iterators in JavaScript with Examples

A Guest Post By: Arfat Salman

Brandon Morelli
codeburst
Published in
6 min readApr 16, 2018

We are going to analyze Iterators in this article. Iterators are a new way to loop over any collection in JavaScript. They were introduced in ES6 and have become really popular since they are widely useful and are used in various places.

We are going to conceptually understand what iterators are and where to use them with examples. We’ll also see some of its implementations in JavaScript.

Introduction

Imagine that you have this array —

const myFavouriteAuthors = [
'Neal Stephenson',
'Arthur Clarke',
'Isaac Asimov',
'Robert Heinlein'
];

At some point, you will want to get back all the individual values in the array for printing them on the screen, manipulating them, or for performing some action on them. If I ask you how would you do that? You’ll say — it’s easy. I’ll just loop over them using for, while, for-of or one of these looping methods.Example implementations would be —

Various looping techniques on arrays

Now, imagine that instead of the previous array, you had a custom data structure to hold all your authors. Like this —

Custom Data Structure

Now, myFavouriteAuthors is an object which contains another object allAuthors. allAuthors contains three arrays with keys fiction, scienceFiction, and fantasy. Now, if I ask you to loop overmyFavouriteAuthors to get all the authors, what would your approach be?You can go ahead and try some combination of loops to get all the data.

However, if you did this —

for (let author of myFavouriteAuthors) { 
console.log(author)
}
// TypeError: {} is not iterable

You would get a TypeError saying that the object is not iterable. Let’s see what iterables are and how we can make an object iterable. At the end of this article, you’ll know how to use for-of loop on custom objects, and in this case, on myFavouriteAuthors.

Iterables and Iterators

You saw the problem in the previous section. There was no easy way to get all the authors from our custom object. We want some kind of method through which we can expose all our internal data sequentially.

Let’s add a method getAllAuthors in myFavouriteAuthors that returns all the authors. Like this —

getAllAuthors implementation

It’s a simple approach. It accomplishes our current task of getting all the authors. However, a few problems can arise with this implementation. Some of them are —

  • The name getAllAuthors is very specific. If someone else is making their own myFavouriteAuthors, they may name it retrieveAllAuthors.
  • We, as developers, always need to know about the specific method that will return all the data. In this case, it’s named getAllAuthors.
  • getAllAuthors returns an array of strings of all the authors. What if another developer returns an array of objects in this format —
[ {name: 'Agatha Christie'}, {name: 'J. K. Rowling'}, ... ]

The developer will have to know the exact name and return type of the method that returns all the data.

What if we make a rule that the name of the method and its return type will be fixed and unchangeable?

Let’s name this method — iteratorMethod.

A similar step was taken by ECMA to standardize this process of looping over custom objects. However, instead of using the name iteratorMethod, ECMA used the name Symbol.iterator. Symbols offer names that are unique and cannot clash with other property names. Also, Symbol.iterator will return an object called an iterator. This iterator will have a method called next which will return an object with keys value and done.

The value key will contain the current value. It can be of any type. The done is boolean. It denotes whether all the values have been fetched or not.

A diagram may help with establishing the relationship between iterables, iterators, and next. This relationship is called the Iteration Protocol.

Relationship between iterables, iterators, and next.

According to Exploring JS book by Dr Axel Rauschmayer

  • 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. That is, it will create iterators.
  • An iterator is a pointer for traversing the elements of a data structure.

Making objects iterable

So as we learnt in the previous section, we need to implement a method called Symbol.iterator. We will use computed property syntax to set this key. A short example is —

Example of iterable

On line 4, we make the iterator. It’s an object with next method defined. The next method returns the value according to step variable. On line 25, we retrieve the iterator. On 27, we called next. We keep calling next until done becomes true.

This is exactly what happens in for-of loop. The for-of loops takes an iterable, and creates its iterator. It keeps on calling the next() until done is true.

Iterables in JavaScript

A lot of things are iterables in JavaScript. It may not be visible immediately, but if you examine closely, iterables will start to show.

These are all iterables —

  • Arrays and TypedArrays
  • Strings — iterate over each character or Unicode code-points.
  • Maps — iterates over its key-value pairs
  • Sets — iterates over their elements
  • arguments — An array-like special variable in functions
  • DOM elements (Work in Progress)

Some other constructs in JS that use iterables are —

  • for-of loop — The for-of loops require an iterable. Otherwise, it will throw a TypeError.
for (const value of iterable) { ... }
  • Destructuring of Arrays — Destructuring happens because of iterables. Let’s see how.

The code

const array = ['a', 'b', 'c', 'd', 'e'];
const [first, ,third, ,last] = array;

is equivalent to

const array = ['a', 'b', 'c', 'd', 'e'];const iterator = array[Symbol.iterator]();const first = iterator.next().value
iterator.next().value // Since it was skipped, so it's not assigned
const third = iterator.next().value
iterator.next().value // Since it was skipped, so it's not assigned
const last = iterator.next().value
  • The spread operator (…)

The code

const array = ['a', 'b', 'c', 'd', 'e'];const newArray = [1, ...array, 2, 3];

can be written as

const array = ['a', 'b', 'c', 'd', 'e'];const iterator = array[Symbol.iterator]();const newArray = [1];
for (let nextValue = iterator.next(); nextValue.done !== true; nextValue = iterator.next()) {
newArray.push(nextValue.value);
}
newArray.push(2)
newArray.push(3)
  • Promise.all and Promise.race accept iterables over Promises.
  • Maps and Sets

The constructor of a Map turns an iterable over [key, value] pairs into a Map and the constructor of a Set turns an iterable over elements into a Set—

const map = new Map([[1, 'one'], [2, 'two']]);
map.get(1)
// one
const set = new Set(['a', 'b', 'c]);
set.has('c');
// true
  • Iterators are also a precursor to understanding generator functions.

Making myFavouriteAuthors iterable

Here’s an implementation that makes myFavouriteAuthors iterable.

Sample implementation of iterable

With the knowledge gained from the article, you can easily understand how the iterator is working. The logic may be a bit hard to follow. Hence, I have written comments with the code. But, the best way to internalise and understand the concept is to play with the code in the browser or node.

If you have any problems, just respond to this article! References:

I hope you enjoyed this guest post! This article was written by Arfat Salmon exclusively for CodeBurst.io

✉️ Subscribe to CodeBurst’s once-weekly Email Blast, 🐦 Follow CodeBurst on Twitter, view 🗺️ The 2018 Web Developer Roadmap, and 🕸️ Learn Full Stack Web Development.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Published in codeburst

Bursts of code to power through your day. Web Development articles, tutorials, and news.

Written by Brandon Morelli

Creator of @codeburstio — Frequently posting web development tutorials & articles. Follow me on Twitter too: @BrandonMorelli

Write a response