# Blogs from the Ranch

< Back to Our Blog

# Generators: Rick Astley and the Sequence of Fibonacci

#### Chris Aquino

On the internet, there are two things that are totally played out: Rick Astley and
the Fibonacci sequence. But finally, in one blog post, they have been combined. Well. Sort of.

This post is an introduction to JavaScript’s generators, added in ES6, the latest version of JavaScript. This update is also known as “ES2015.”

## What is This… Generator?

In a nutshell, generators are functions that can be paused
and resumed. They are useful for things like incrementally
creating very large sequences.

More importantly, they create sequences that are iterators.

## The Way of Iteration

If you’ve worked with arrays, you have likely had to iterate
through the elements of that array. There are a few ways you can do this in JavaScript.

One way is to use the very boring (but very fast) for-loop:

``````let numbers = [0, 1, 1, 2, 3, 5, 8, 13];
for (let index=0; index < numbers.length; index++) {
console.log(`This number is: \${numbers[index]}`);
}

``````

That snippet of code prints out the first few Fibonacci numbers to the console, as you might expect.

Another way to go through the elements is to use the `forEach` method
on an array. When you pass a function argument to `forEach`, `forEach` will visit each element in the array. As it visits each element, it invokes your
function argument and passes it that element.

``````let numbers = [0, 1, 1, 2, 3, 5, 8, 13];
numbers.forEach((number) => {
console.log(`This number is: \${number}`);
});
``````

Here, we’ve passed an anonymous arrow function to `forEach`, but you can also use named functions or regular (non-arrow) anonymous functions. The arrow function expects
to receive the current item being visited by `forEach` and gives it the
label `number`, which is then used inside the body of the arrow function.
Some developers prefer `forEach` because they find it more expressive than
a for-loop.

## Iterating using the for..of syntax

ES6 provides another way of doing iteration: by using `for..of`.

``````let numbers = [0, 1, 1, 2, 3, 5, 8, 13];
for (let number of numbers) {
console.log(`This number is: \${number}`);
}

``````

Like a for-loop, you use the `for` keyword. But inside of the parentheses, you specify a variable that will point to the current element. Inside the curly braces, you write the body as usual.

Ok, great! Yet another way to work with array elements. Admittedly, it’s
not all that exciting. But, `for..of` isn’t limited to arrays. You can
create custom iterators that work with `for..of`.

## Building a Custom Iterator

There are two new pieces of syntax that let you create custom iterators:
`function *` and `yield`.

Here’s how you would write our not-so-exciting example using that syntax:

``````function * numbers() {
yield 0;
yield 1;
yield 1;
yield 2;
yield 3;
yield 5;
yield 8;
yield 13;
}

for (let number of numbers()) {
console.log(`This number is: \${number}`);
}

``````

First, you declare a function using the `function *` syntax.
This tells the JavaScript engine that this function will generate
an iterator. You could say that this is a…generator function.

Some developers prefer to put the `*` right beside the
function name, like so:

``````function *numbers() {
yield 0;
yield 1;
yield 1;
yield 2;
yield 3;
yield 5;
yield 8;
yield 13;
}
``````

(That is the style that will be used for the rest of this blog post.)

Inside of your generator, you `yield` at least one value.

When you call a generator, it returns an iterator.
`for..of` knows to “ask” an iterator for its next value.
The iterator `yield`s its values until there are no more `yield`
statements.

Obviously, you wouldn’t want to use this syntax to spit
out a bunch of values you could just put into an array.
Let’s continue with the tried and true Fibonacci sequence in the next example.

## “Hello, Fibonacci!”

One of the ways you might use generators is to create a sequence
of calculated values. Here is a generator that produces a
sequence of Fibonacci numbers.

``````function *fibonacci() {
var n1 = 0;
var n2 = 1;
while(true) {
yield n1; // yield the first number.

// Calculate the next Fibonacci number
[n1, n2] = [n2, n1 + n2]; // Destructuring assignment!
}
}
``````

You might think that calling `fibonacci` would try to produce
an array of infinite length. But, it doesn’t. It only does enough work to prepare the next value in the sequence.

Notice that the `yield` is inside of a `while(true)` statement.
Generators pause their execution until the next time that `for..of` asks
for another value.

Of course, if you try to iterate over `fibonacci` with `for..of`, it will
run forever unless you `break` out of it. Or, your browser will simply
crash after a few seconds:

## Iterators, Behind the Curtain

So, to recap: generator functions return iterators. But how do iterators work? What exactly is `for..of` doing with an iterator to get those values out?

To answer that, consider the following generator:

``````function *roll() {
yield "Never gonna give you up";
yield "Never gonna let you down";
yield "Never gonna run around and desert you";
yield "Never gonna make you cry";
yield "Never gonna say goodbye";
yield "Never gonna tell a lie and hurt you";
}
``````

As mentioned earlier, to get the iterator, simply call the generator.

``````let rick = roll();
``````

To get the next value, invoke the `next` function on the iterator,
which will cause it to yield its first value.

``````rick.next();
// {value: "Never gonna give you up", done: false}
``````

Notice that the value returned is an object with two properties, `value` and `done`.
The `value` property is what the iterator `yield`ed. The `done` property signals
whether or not there are more values.

If you continue to call `rick.next()`, you’ll find that the iterator is eventually
drained of its values:

``````...
rick.next();
// {value: "Never gonna say goodbye", done: false}

rick.next();
// {value: "Never gonna tell a lie and hurt you", done: false}

rick.next();
// {value: undefined, done: true}
``````

When an iterator has no more values to `yield`, the `value` property is `undefined`, while the `done` property is now `true`.

Knowing how an iterator works, you could write a simple implementation of `for..of`
that uses callbacks:

``````function forOf(iter, callback) {
let result = iter.next();
while (!result.done) {
callback(result.value);
result = iter.next();
}
}
``````

And that function could be used like so:

``````forOf(roll(), (val) => { console.log(val); });
``````

## Iterable Iterators and Potent Potables

Generators (things that produces iterators) and iterators
(things that can be iterated over) work based on two separate protocols: the iterable protocol and the
iterator protocol.

A generator function is really just syntactic sugar
for implementing the iterable protocol. This protocol
specifies that an object must have a method named
`[Symbol.iterator]`. (That’s a method whose name
is the ES6 constant `Symbol.iterator`.)

This `[Symbol.iterator]` method can return any object, as long
as it is an iterator, meaning that it implements the iterator protocol.

The iterator protocol says that an iterator needs to have
a `next` method, and that `next` should return an
object with a `value` property and a boolean `done` property.

Here is an example of an object literal version of our
generator function.

``````let astley = {
[Symbol.iterator]() {
return this;
},
values: [
{
value: "Never gonna give you up",
done: false
},
{
value: "Never gonna let you down",
done: false
},
{
value: "Never gonna run around and desert you",
done: false
},
{
value: "Never gonna make you cry",
done: false
},
{
value: "Never gonna say goodbye",
done: false
},
{
value: "Never gonna tell a lie and hurt you",
done: false
},
{
value: undefined,
done: true
}
],
next() {
return this.values.shift();
}
};
``````

The `[Symbol.iterator]` method simply returns a reference to itself, since
it also implements the `next` method. `[Symbol.iterator]` is not required
to `return this` — you are free to make your iterables separate from your
iterators. In this example, we made our iterable and iterator the same object.

You could use your iterable object like so:

``````for (let lalala of astley) {
console.log(lalala);
}
``````

The `for..of` construct implicitly calls `astley[Symbol.iterator]` to get the iterator object. Then it calls the `next` method over and over until the
value of the `done` property is `true`.

The object literal version is much more verbose than our generator function.
But, it is a good option if you already have an object that encapsulates some
sort of computed sequence and you want to use it with `for..of`.

## Summary

Generators were added to JavaScript in ES6. When combined with `for..of`, they provide an easy way to create and consume sequences of values.

They have good support in evergreen browsers such as Chrome, Firefox and Edge. In older browsers
(e.g., IE < 9 and Safari < 9), you will want to transpile your code using a tool like Babel.

Stay tuned for upcoming posts about generators and iterators, in which we’ll look at error handling, recursion and coroutines.