//

ES6 ITERATORS & FOR..OF

To loop over an array or a collection JavaScript has been traditionally using for loops. ES5 introduced the for ..each loop. But ES6 introduces a little shorter version, a new interface for iteration called Iterable.

Let's look at the traditional for loop:

for loop

var items = ['item1', 'item2', 'item3'];

for (var i = 0; i < items.length; i++) {
  console.log(items[i]);
}

forEach loop

With ES5, you can use the built-in forEach method:

var items = ['item1', 'item2', 'item3'];

myArray.forEach(function (item) {
  console.log(item);
});

This is shorter than the for loop but still you can't break out of the loop using the break statement.

For..in

For..in loop iterates through the properties of an object so this is not the ideal solution.

for..of loop

ES6 introduces for..of loop.

  var items = ['item1', 'item2', 'item3'];

  for (var item of items) {
    console.log(item);
  }

Let's look at why it is better than its predecessors:

  • It avoids the pitfalls of for..in
  • Unlike forEach(), it works with break, continue, and return
for..in vs for..of

The for–in loop is for looping over object properties. The for–of loop is for looping over data and array-like objects.

Collections support for for..in loop

for..in works for other collections apart from the arrays as well.

Map and Set

for..in works for Map & Set objects of ES6. A Set object can be used to eliminate duplicates:

  var uniqueWords = new Set(words);

  for (var word of uniqueWords) {
    console.log(word);
  }

The data inside Map is made of key-value pairs. You can use destructuring to unpack these pairs into seprate variables:

  var uniqueWords = new Set(words);

  for (var word of uniqueWords) {
    console.log(word);
  }
Objects

for..of does not work with plain old Objects, but if you want to iterate over an object’s properties you can either use for..in or the built-in Object.keys().

Iterators

Iterator enables JavaScript objects to define custom iteration like CLR IEnumerable or Java Iterable.

This will generalize for..in to custom iterator-based iteration with for..of.

@@iterator

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.

Let's look at an example:

var foo = "foo",
iter1, iter2, iter3, iter4,
iterator;

iterator = foo[Symbol.iterator]();

iter1 = iterator.next();
iter2 = iterator.next();
iter3 = iterator.next();
iter4 = iterator.next();

console.log(iter1); // done: false, value: "f"
console.log(iter2); // done: false, value: "o"
console.log(iter3); // done: false, value: "o"
console.log(iter4); // done: true,value: undefined