Making plain JS objects iterable — I

Jyotika Banerjee
3 min readFeb 24, 2020

--

Photo by JESHOOTS.COM on Unsplash

I have been brushing up my ES6 skills and trying to wrap my brain around iterators and generators. I wanted to make plain JS objects iterable, using generators. I’ll write about this in two parts. The first part is a bite sized refresher on a few ES6 concepts we will use in the process — iterables, generator functions, symbols etc.

Here’s a quick code snippet to note how we would print keys, values and entries for:
- Iterables (Arrays, Maps, Sets etc.) &
- Plain JS objects which are non-iterable.

For iterable objects in JS

Methods of iterables

Corresponding functions for plain JS objects

Methods of objects

Generator Functions

Photo by American Public Power Association on Unsplash

To quote the book Exploring ES6:

You can think of generators as processes (pieces of code) that you can pause and resume.

Every time a yield statement is intercepted, the code will pause, returning what you have up until that point, to the caller. Invoking a next() on the generator object, will allow the generator function to resume, until the next yield statement, which will continue this pause/play behavior described above. Finally, when there is a return statement or end of block, the process will end. We can see this in the code below:

Using generator functions
/** Output **Returning bulgogi first.
genObj.next() {value: 1, done: false}
Returning samgyeopsal second.
genObj.next() {value: 2, done: false}
genObj.next() {value: "The End", done: true}
***/

Symbols

This is the new primitive data type introduced by ES6. We use the Symbol() factory function to create symbols. The Symbol function is invoked/called, not instantiated.

let mySym1 = new Symbol("foo"); // TypeError
let mySym2 = Symbol("bar");

Every single call to the Symbol function generates a unique new symbol. Note that the function allows you to provide a descriptive string. That’s not the symbol’s value, its just a descriptive text for the symbol you’re creating.

Therefore:

Symbol("foo") === Symbol("foo"); // false

The primary use case for Symbols is : to create unique property keys.

//From the book
const MY_KEY = Symbol();
const obj = {};

obj[MY_KEY] = 123;
console.log(obj[MY_KEY]); // 123

Symbol.iterator

It is the property that specifies the default iterator of an object. This property is NOT writable, enumerable or configurable.

When you read about iteration protocols in JS on MDN, you come across the following:

In order to be iterable, an object must implement the @@iterator method, meaning that the object (or one of the objects up its prototype chain) must have a property with a @@iterator key which is available via constant Symbol.iterator

Iterable JS objects already have this set up for them, whereas for plain JS objects, we would have to create this key to make them iterable.

The following code demonstrates how to work with Symbol.iterator for Sets:

let set = new Set([1,2,3,4,5]);
console.log(set); // Set(5) {1, 2, 3, 4, 5}
let iter = set[Symbol.iterator]();
console.log(iter); // SetIterator {1, 2, 3, 4, 5}
iter.next(); // {value: 1, done: false}

In the example above, we use the Symbol.iterator key of the Set object to get access to its iterator method and then invoke it to get the iterator object. We then call the next() function of the iterator object, to iterate over the values of set.

Computed property names & Concise method syntax in Es6

Unlike how they sound, these are two really easy and convenient new features that are provided by ES6. They are better demonstrated by example.

Computed property names & concise method syntax
  • We assigned the property name to a variable called prop . The expression [prop] evaluates to the value of the variable, i.e.'name' . This works, we were able to print the name by referring to the property in the console.log statement.
  • Note how a function expression was not needed to define it, we are able to directly declare the method. A succinct shorthand.

In part II, we will deep dive into making plain JS objects iterable, using generators.

References:

Every web developers source of truth : MDN
The book ‘Exploring ES6’ by Dr. Axel Rauschmayer
(It was recommended to me by my friend and mentor, BP Mishra dada, who guides me in every endeavor to learn anything Web/Frontend.)

--

--