Overview
Javascript’s new version (EcmaScript 6) has some amazing new features. The ones discussed in this post is iterators and generators. More information can be found here.
Details
Iterator
Iterators allow you to go through every element inside an abstract data type the same way without having to know how it’s been implemented. Java has the Iterable interface which forces you to implement the next()
and hasNext()
methods. ES6 has only 1
method, next()
that has 2 return values.
1
2
3
4
5
// Not at the end
return { done:false, value:"returnValue" };
// After last element
return { done:true, value:"optionalEndValue" };
To iterate over an object, you need the next()
method and you need your object to be iterable. To make your object iterable you do the following.
1
2
3
4
5
6
7
8
class MyObject {
...
[Symbol.iterator](){
...
// this iterator has the next function mentioned above
return aIteratorYouCreated;
}
}
Now that you have the iterator, you want to iterate over its elements. To do this, we use es6’s new for ... of
loop.
1
2
3
4
5
6
7
8
for (let value of iterable) {
console.log(value);
}
// for arrays, we can use entries which have both index and value
for (let [index, value] of someArray.entries() ) {
console.log(`${index} - ${value}`);
}
Generators
Generators are functions that allow you to pause and resume. They use the yield
key instead of the return
key.
When the generator is called the first time, it runs until it hits the first yield
and then stops. When called again, it will run until the next yield
. It will continue this way until it finishes. Generators in python work the same way. That’s because ES6 got them from Python.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
function* generatorFib(){
prev = 0;
curr = 1;
yield 0;
yield 1;
while (true) {
temp = curr;
curr += prev;
prev = curr;
yield curr;
if (curr == 2) {
break;
}
}
}
// first 5 fib numbers
let fibs = generatorFib();
fibs.next(); // { done:false, value: 0}
fibs.next(); // { done:false, value: 1}
fibs.next(); // { done:false, value: 1}
fibs.next(); // { done:false, value: 2}
fibs.next(); // { done:true }
We can also iterate through a generator
1
2
3
4
5
6
7
for (let fib of fibs) {
console.log(fib);
}
// 0
// 1
// 1
// 2