What the... iterators?
Tags: javascript, iterators, loops, forof
Published: 2018-05-03 18:26:35

---
title: What the... iterators?
published: true
description: Iterators in Javascript
tags: #javascript, #iterators, #loops, #forOf
---

#ITERATORS are not that scary...

According to the _MDN web docs_:

> The _for...of_ statement creates a loop iterating over **iterable** objects, , invoking a custom iteration hook with statements to be executed for the value of each distinct property of the object.

Ok... hm... but what's that Iterable object?

We use iteration almost every time we code... with stuff like: _map, filter, for, forEach, ecc..._

But the _for...of_ statement is special, because:

> Iterators (...) bring the concept of iteration directly into the core language and provide a mechanism for customizing the behavior of _for...of_ loops.

So you can think that the _for...of_ loop knows how to iterate over an array... but that's not true!.
We need the **iterator** object as "interface" to loop over it:

<center>_for...of <------> **ITERATOR** <------ array_</center>

Now that we know this... let code it:

```js
const dogs = ["labrador","chow-chow","cavalier"];

for (let breed of dogs)
	{
		console.log(breed);
	}
//-> labrador, chow-chow, cavalier

```

Behind that... we've the **iterator** object that looks like this:

```js
const dogs = ["labrador","chow-chow","cavalier"];

let iterator = dogs[Symbol.iterator]();

for (let breed of iterator )
	{
		console.log(breed);
	}

//-> labrador, chow-chow, cavalier (the same result)

```

### wait... WHAT?

<center>![what](https://media.giphy.com/media/1nHK1JcpgGZNu/giphy.gif)</center>

Yes... that seems really strange, but It's not that bad.
Let's quote, again:

>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 **Symbol.iterator** key. This function should return a new iterator for each call, however, this is not a requirement.

That `Symbol.iterator` is the property every **iterable** object needs, to loop over It.

Iterable objects can be:

String
Array
Map
Set
nodeList
...

and all these possess that property, behind the scene.

#Symbol.iterator

The property provides us, the `next()` method, that works like this:

```js
const dogs = ["labrador","chow-chow","cavalier"];

let iterator = dogs[Symbol.iterator]();

console.log(iterator.next())

//-> {value: "labrador", done: false}

```

Every time we call the `next()` method, we loop over the **iterable** object.

Now we've got two keys:
_value: "labrador"_
(the current value of the **iterable** object)
_done: false_
(will be _false_ until we've values inside of it!)


```js
const dogs = ["labrador","chow-chow","cavalier"];

let iterator = dogs[Symbol.iterator]();

console.log(iterator.next())
//-> {value: "labrador", done: false}
console.log(iterator.next())
//-> {value: "chow-chow", done: false}
console.log(iterator.next())
//-> {value: "cavalier", done: false}
console.log(iterator.next())
//-> {value: undefined, done: true}

```

`done:true` is the ending point for the **iterable** object.

There are some other powerful tools in _JS_ that need the object to be **iterable**

```js
//TAKE A LOOK AT THE SPREAD OPERATOR...

const number = 31;

let count = [...dogs];

//-> TypeError: dogs is not iterable

const dogs = "labrador";

let doggy = [...dogs];

console.log(doggy)

//-> ["l", "a", "b", "r", "a", "d", "o", "r"]

```

You've to be _always_ careful about this, and use only **iterable** objects with tools like these!.

<center>![danger](https://media.giphy.com/media/3o7Zemg33eB4BFOeRi/giphy.gif)</center>

I want to say _byebye_ adding a bit of spice:

`Symbol.iterator` is a property... **so**... you can create your own **iterable** object if you want to!

For more info:

[The mighty MDN guide](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators)

<center>**Have fun with it!**</center>