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
, andreturn
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