Going Over Iterators … of Javascript

ES6 makes a big push to improve Iterators and for a good reason. Iterating over a set of values, where you are either transforming, or using or saving it in some way is a damn big deal, everyone does it and should know how to do it better; its 50% of the job.
So I am glad the new ECMAScript specification makes traversing over Javascript data structures cleaner and easier.
There are three concepts central to iteration:
- Iterable is a data structure that makes its elements accessible to the public through iteration.
- Iterator is a pointer to the next element in the iteration.
- Iterability is an event where data consumers get their data from Iterable data sources with the help of Iterator.

In order to standardize Iterability, so every data consumer could access every data source, ES6 introduced the Iterable interface.

But given that Javascript does not have interfaces, Iterable is more of a convention. Most people call it the Iterable Protocol. It’s really just a way to create an Iterable Data Source by adding a “special” function to an object.

Iterable data sources
A few built-in classes that implement the iterable protocol include Array, String, Map, Set and NodeList.
Those unfamiliar with Map & Set should read about them in my prior article:
String
To loop through a data source we’ll use for… of loop. Here is how I’d loop through every letter in a string.
console output:
I r è n e J o l i o t — C u r i e
But string is a primitive value, how can it be iterable? Well, Iterable doesn’t have to be Array or object. As long as it can be reimagined as a stream, which gets coerced to objects before the iterability takes place.

Array
Looping through Array is just as easy. The best part is that code for the most part is identical to looping through a String.
console output:
I r è n e J o l i o t — C u r i e

Map
Looping through a Map is a little different, since a Map is iterated over its entries. The entries are iterated in the same order in which they were added to the map.
console output:
Irène
Set
Looping through the Set is similar to Map. The entries iterated over in the same order in which they were added to the Set.
console output:
Irène
NodeList
Looping through NodeList
Custom Iterable Objects
Making a custom iterable data source is simple. Just add a custom function with a custom name coming from Symbol.iterator, like so:
object[Symbol.iterator] = function ()
That function must return an object with a function next() which returns an object with 2 properties value & done.

Here is an example, where I create a custom String object. I am not using ES6 to create a class in this case since I need to implement a private variable.
- The MyString class has a method [Symbol.iterator], which returns another object with next() method in it.
- The next() method will return an object with value and done properties.
- The for…of Iterability finishes when next() returns an object with done equals true.
Iterable computed data
Not every object needs to implement the Iterable protocol.
For example, all the Javascript Iterable structures (Array, String, Map & Set) have three methods that return iterable objects.
- entries() returns an Iterable Array with every entry as an array with [key, value] pairs
- keys() returns an Iterable of keys
- values() returns an Iterable of values


In order for you to make an object iterable, all that needs to happen is you transform that object into another Iterable structure.
Iterating Language Constructs
These language constructs were designed to iterate over Iterables
Destructuring pattern
This one is pretty useful when you are sure of the variables that would make it into the newly made variables.
console output:
item1 [“Egg Roll”, 1.2]
item2 [“French Fries”, 1.95]
itemB [“Egg Roll”, 1.2]
for-of
The for-of is a new loop that replaces for-in and forEach() and supports the new iteration protocol.
Array.from
This construct converts an “iterable” data source into an Array. Here is an example of converting a String.
Spread operator
Helps us create an Array from any Iterable data source, or insert those values into an array.
console output:
* insertion [“a”, “g”, “h”, “d”, 12, 5, 8]
* copy [12, 5, 8]
Sets & Maps Constructors
Both of the data set constructors support an iterable object as input. For Map every element in iterable must be an array with two elements, a key-value pair.
The Set will add all of iterable object’s elements to the new Set.
Implementing tool functions
Array.from is a good example of a built in tool function. Usually, you’d make a tool function for an object that doesn’t support the iterable protocol for a particular object. The tool function must return an Iterable.
The following tool function converts an object into an Iterable and iterates over its values.
console output:
[true, false, true]
Using Generators instead
Most people find it easier to create a Generator instead of making an Iterable via the protocol. I’ve dedicated an entire section on how to create Generators in my prior article:
Combinators
Combinators are similar to tool functions, but instead of turning one data source into an Iterable, they focus on iterating multiple data sources or iterating only over part of a data source.
Conclusion
Javascript has evolved considerably making the day to day development easier with new language constructs. We no longer have to rely on other libraries to re-construct or iterate over our data.
