The Importance of Iteration Protocols
Tags: javascript, iterator, iterable, protocols
Published: 2017-12-09 18:08:34

---
title: The Importance of Iteration Protocols
published: true
description: Let's talk about the importance of iteration protocols, and how valuable they're to the javascript language
tags: js, iterator, iterable, protocols
---

Hey everyone, recently I caught myself talking to a great friend of mine ([Maksim Ivanov](http://maksimivanov.com/), he writes some really useful articles) about iteration protocols in javascript, during the discussion we were very happy with the language improvements that these protocols bring and we also noticed even more things about it, because of this discussion, I decided to write this article.

Let's get started then, first, let me list the topics that I want to talk about:

- [Iteration Protocols?](#iteration-protocols)
- [Its true value](#its-true-value)
- [for..of](#for-of)
- [Creating a custom iterator](https://nipher.io/the-importance-of-iteration-protocols/#creating-a-custom-iterator)
- [Built-in iterables](https://nipher.io/the-importance-of-iteration-protocols/#built-in-iterables)
- [Iterating over objects](https://nipher.io/the-importance-of-iteration-protocols/#iterating-over-objects)
- [Other languages](https://nipher.io/the-importance-of-iteration-protocols/#other-languages)
- [Conclusion](https://nipher.io/the-importance-of-iteration-protocols/#conclusion)

<h2 id='iteration-protocols'>Iteration Protocols?</h2>

Ok, if you don't even know what I'm talking about, I'll explain it real quick and show an example.

Among the iteration protocols we have the Iterable and the Iterator.

Let's check them out separately:

#### Iterable

This protocol simply defines a way to specify the iteration behavior of an object.  
So for example, we have a string object `'Hello World'`, the object itself will tell how its iteration should be like.

How's that? 

Well, let's see a code snippet and explain its code, I believe it'll be easier to understand.

```javascript
const message = 'Hello World'

console.log(message[Symbol.iterator])
// > ƒ [Symbol.iterator]() { [native code] }

console.log(message[Symbol.iterator]())
// > StringIterator {}
```

So, wtf?

Let's go through it:

- A string is created and assigned to the `message` constant
- We use `message[Symbol.iterator]` to access a function (which will return an iterator)
- We call the function, which returns a `StringIterator` (which implements the Iterator Protocol)

That's the iterable protocol, having the `[Symbol.iterator]` defined, so anyone can call it and get its iterator, which can be used to get the values to be iterated.

As you might have noticed, we didn't need to implement/define it, the string object already has a `[Symbol.iterator]` defined, it comes from its prototype (`String.prototype[Symbol.iterator]`), that's not the case for all types of objects, we'll talk more about it on the topic "Built-in iterables".

#### Iterator

This protocol is basically an interface for getting sequencial values.

If you think about it for a bit, that's what an iteration is about, getting values sequencially from something. And you'll also realize how many different types of objects we usually want to iterate over:  
Arrays, Strings, Map, Set, DOM data structures, Streams, Objects...

Now, in case we want to get sequencial values from one of these guys, we could use the iterator protocol to do so.

An iterator needs to implement this interface:

```javascript
{
  next() {
    return { value: <Anything>, done: <Boolean> }
  }
}
```

Let's use a string again, so we can see these two protocols working together:

```javascript
const message = 'Hello'

const messageIterator = message[Symbol.iterator]() // > StringIterator {}

console.log(messageIterator.next())
// > { value: 'H', done: false }
console.log(messageIterator.next())
// > { value: 'e', done: false }
console.log(messageIterator.next())
// > { value: 'l', done: false }
console.log(messageIterator.next())
// > { value: 'l', done: false }
console.log(messageIterator.next())
// > { value: 'o', done: false }
console.log(messageIterator.next())
// > { value: undefined, done: true }
```

Well, I guess it's starting to make some sense, right?

Let's go through it real quick

- We define the string and get an instance of its iterator from it
- We start calling `next()` from the iterator instance (the interface that I mentioned)
- Each value returned by `next()` is a letter from the string
- It returns letters in a left -> right order from the string
- When there are no letters left, we get `undefined` as a value and `true` as done (which means there're no more values)

If you think about it, it's a very simple interface and yet it brings a lot of value to the javascript language.

<h2 id='its-true-value'>Its true value</h2>

As I glimpsed before, we have a lot of cases which we would like to iterate over some kind of structure/object.

We didn't really have a well defined interface for doing it, resulting in different ways to iterate over stuff.

A lot of libraries solved this problem for us, `lodash` for example:

```javascript
_.forEach('Hello', value => console.log(key))
// > 'H' 
// > 'e'
// > 'l'
// > 'l'
// > 'o'

_.forEach([1, 2], value => console.log(value))
// > 1 
// > 2
 
_.forEach({ 'a': 1, 'b': 2 }, (value, key) => console.log(key))
// > 'a' 
// > 'b'
```

As you can see above, one single function `.forEach(...)` which works with any kind of object (String, Array, Object).

But it was about time, that the language itself would improve that, so we wouldn't need a library to execute such a simple thing in a programming language.

Don't get me wrong, I love lodash and such, and they're still super useful and relevant today, they themselves can use and benefit from the iteration interfaces, and they do, imagine how simpler it is to implement their `_.forEach` method now than it was before.

That's the real value, the combination of simplicity, consistency and well defined patterns.

<h2 id='for-of'>for..of</h2>

So, how can we use these protocols in a generic way?

Now, we have `for (let value of <iterable>) { ... }`.

As you can see, it's different than the `for` we're used to.

Let's check some `for..of` examples:

```javascript
const message = 'Hello'

for (let letter of message) {
  console.log(letter)
}

// > H
// > e
// > l
// > l
// > o

const list = [1, 2, 3, 4, 5]

for (let i of list) {
  console.log(i)
}

// > 1
// > 2
// > 3
// > 4
// > 5

const person = new Map([['name', 'jonas'], ['age', 23]])

console.log(person)
// > Map { name → "Jonas", age → 23 }

for (let [key, value] of person) {
  console.log(`${key}:`, value)
}

// > name: Jonas
// > age: 23
```

How about `for..in`?

It's still different.

The `for..in` iteration does not use iteration protocols, it iterates over enumerable properties of objects, unless the property's name is a `Symbol` or defined via `Object.defineProperty` setting `enumerable` to `false`.

This also means it would also iterate over its prototype properties (if they fit the description above).

You can avoid such thing by adding a conditional `if (obj.hasOwnProperty(prop)) { ... }` inside your `for..in` block, so it will execute the code only for properties of the actual instance.

However, you can avoid `for..in` if you wish, and use iteration protocols with `Object` instances like you would use `for..in` (without the necessity of the conditional though), make sure to use one of the static methods when using `for..of` with `Object` types, for example: `Object.entries`

I'll show how it looks like on the topic "Iterating over objects".

<h2 id='creating-a-custom-iterator'>Creating a custom iterator</h2>

One interesting thing to point out, is that these protocols are not stricted to be implemented only in the javascript engines, it's also possible to create a custom one.

Let's check an example?

```javascript
function rangeOf(n) {
  let i = 1
  const range = {}

  range[Symbol.iterator] = () => ({
    next() {
      let [value, done] = (i <= n ? [i++, false] : [undefined, true])
      return { value, done }
    }
  })

  return range
}

for (let i of rangeOf(5)) {
  console.log(i)
}

// > 1
// > 2
// > 3
// > 4
// > 5
```

Ok, once more, let's go through the code...

Hey, I hope you're enjoying it, read the rest of this article on my website, so I get some access and comments over there too.

I worked hard redesigning it and making it super nice for you :) 

**Access it Here**: [Post Link](https://nipher.io/the-importance-of-iteration-protocols/)

Thank you!