Be the first user to complete this post
|
Add to List |
Getting started with es6 iterators and iterables
ES6 iterators provide a very simple way to iterate on objects, quite similar to the way iterators work in Java. In this post, I will briefly discuss the main concepts behind ES6 iterators and then dive into some examples using arrays. Future posts will discuss using ES6 iterators with other kinds of objects. This article is the second installment of our Learning ES6 series.
- Part 1: Getting started with ES6 modules
- Part 2: Getting started with ES6 iterators and iterables - THIS ARTICLE
- Part 3: ES6 iterators and iterables - creating custom iterators
- Part 4: Getting started with ES6 generator functions
- Part 5: Generators and Yield in ES6
A brief introduction
There are a few things you ought to know before we jump in and see some examples.- There are two main types of entities to be aware of:
iterables
anditerators
. - Iterables are things that can be iterated upon, like arrays, Maps, Sets.
- Primitive javascript objects are not iterable.
- Anything that implements the
next()
function can be considered to be an iterator. - The result of invoking
next()
is (almost) always object of the form{value: some_value, done: true|false }
. - Any object/function can be turned into an iterable if it has a key called
Symbol.iterator
which refers to a function that returns an object with thenext()
function.
NOTE: If your browser does not support running all the follwing examples, you can try them out at es6fiddle.net.
Basic iteration
Arrays are the simplest and the most common iterables. Traditionally, you could iterate on arrays as followsvar numbers = ['a', 'b'];
for (var num in numbers) {
console.log(num);
}
Using the new ES6 iterators you can iterate on an array as follows:
var numbers = ['a', 'b'];
var iter = numbers[Symbol.iterator]();
console.log(iter.next()); // Prints {value: "a", done: false}
console.log(iter.next()); // Prints {value: "b", done: false}
console.log(iter.next()); // Prints {value: undefined, done: true}
In ES6 Symbol.iterator
is a non-string key for iterables that is invoked to create an instance of an iterator. In fact, Symbol
is a completely new primitive type in ES6. As you can tell in the above code, the key is already available on the Array primitive type. All we did was invoke it to create a new iterator.
Also, in the above code, notice how the last value of iter.next() returns the done as true
. This can be used in your program to determine if there are more items to iterate on.
Having to invoke Symbol.iterator
on a primitive like arrays seems like a bit of an overhead. Thats not to worry because you can also use Array.prototype.entries()
to create the exact same iterator, albeit in a much more convenient syntax.
var numbers = ['a', 'b'];
var iter1 = numbers.entries();
// is equivalent to
var iter2 = numbers[Symbol.iterator]();
The entries() function is available on ES6 primitives like arrays, typed arrays, maps and sets. In fact, they also have two more useful functions - keys() and values() which do pretty much what you think they do.
Different ways to iterate
Another point to note is that depending on the way you iterate, you can expect a different kind of output. For example.var numbers = ['a', 'b'];
var iter1 = numbers.entries();
console.log(iter1.next()); // Prints {value: "a", done: false}
console.log(iter1.next()); // Prints {value: "b", done: false}
console.log(iter1.next()); // Prints {value: undefined, done: true}
// Compare the above output to the following
for (var item of numbers.entries()) {
console.log(item);
}
// Output
// [0, "a"]
// [1, "b"]
Notice in the above code, we had to use the for..of loop for this to work instead of the for..in loop. As far as the output is concerned, the first item of the output array represents the key
in the entry, which in our case is the index, and the second item in the output array is the actual value of the numbers array.
The return value of the entries()
function makes it suitable candidate for being used along with the spread operator.
for (var [index, item] of numbers.entries()) {
console.log(index, item);
}
// Output
// [0, "a"]
// [1, "b"]
If you wish to, you can also iterate on the keys itself. This isin't as useful in the case of arrays but comes in really handy when you are using Maps
.
var coordinates = new Map();
coordinates.set('x', 10);
coordinates.set('y', 20);
for (var item of coordinates.keys()) {
console.log(item);
}
// Output
// x
// y
NOTE: ES6 Maps, unlike regular javascript objects, return values based on insertion order when iterated on.The next and final utility function on primitives is the
value()
function. And as you would expect, it lets you iterate on the values.
var coordinates = new Map();
coordinates.set('x', 10);
coordinates.set('y', 20);
for (var item of coordinates.values()) {
console.log(item);
}
// Output
// 10
// 20
That covers all the ways in which you can use the new ES6 iterators. In the next article, we will see more examples of creating and using your own iterators and also discuss some of the optional but often times necessary functions like return()
.
Also Read:
- Using es6 modules with simple examples
- css: margin does not work
- Progressive enhancement vs Graceful degradation
- The JavaScript Prototype Property - Visualized
- Split a string in javascript when both comma and spaces are present