Using ES6 Generators

I’ve been having fun using some newer technology recently - namely ECMAScript 6 Harmony (or at least the bits of it that Chrome supports). One particular feature which I’ve been using has made life quite a lot easier for me - ES6 now supports Generator functions, and they can be used to implement iteration with objects.

What Are Generators?

If you’ve never used them before, a Generator is a function that can be used as an iterator - I.E. you can use them in a for-each loop, much like you would an array. The difference between using a Generator and a function that returns an Iterable (e.g. an Array), is the Yield keyword, which acts like a return statement except that it returns the next iterable value.

This means that we don’t have to have a list of the objects we want to iterate over, the list can be built as you iterate, meaning you only use as much memory as necessary for the loop, instead of the maximum amount needed to store the entire data structure.

Sometimes there are no apparent benefits to using Generators, but if you find yourself traversing a data structure repeatedly, you’re going to have a lot of repeated code, and using Generators can save you the hassle of repeating yourself.

Generators aren’t unique to ECMAScript - they can be found in many languages. Read about using them in Python here.

Using Generators

A Generator function is noted by function*:

function* myGenerator() {
yield 1;
yield 2;
yield 3;
}

We can either use our Generator as an object:

var gen = new myGenerator();

console.log(gen.next()); //1
console.log(gen.next()); //2
console.log(gen.next()); //3

Or access it as a function:

for(var x of myGenerator()) {
console.log(x);
}
>> 1
>> 2
>> 3

But that’s not much good to us! We want to be able to overwrite an Objects Symbol.iterator, so that we can iterate the object directly.

function IterableObj() {
this.data = [1,2,3,4,5,6,7,8,9,10,11,12]
}

IterableObj.prototype[Symbol.iterator] = function* () {
for(var x of this.data) {
yield x * 4;
}
}

var myObj = new IterableObj();
for(var data of myObj) {
console.log(data);
}

>> 4
>> 8
>> 12
>> 16
>> ...

So those are the basics of using ES6 Generators. Check out some of the links below for further reading!