Using Generators Like Regular Variables

Go to Nav

In JavaScript, you can create iterable objects using generators.

Purpose

You can turn infinite functions, like those calculating Fibonacci numbers, into controllable iterables.

Syntax

function* fibonacciGenerator() {
    let [prev, curr] = [0, 1];
    while (true) {
        yield curr;
        [prev, curr] = [curr, prev + curr];
    }
}

const fibonacci = fibonacciGenerator();

console.log(fibonacci.next().value); // 1
console.log(fibonacci.next().value); // 1
console.log(fibonacci.next().value); // 2

// Alternatively, use a for...of loop to print the Fibonacci sequence (note: termination condition is needed)
for (const value of fibonacci) {
    console.log(value); // 3, 5, 8, ...
    if (value >= 13) break;
}

This is the most common generator syntax.

However, it lacks encapsulation and feels like simply using the generator as is.

Improvement

const fibonacci = {
    prev: 0,
    curr: 1,

    valueOf() {
        const value = this.curr;
        [this.prev, this.curr] = [this.curr, this.prev + this.curr];
        return value;
    },

    *[Symbol.iterator]() {
        while (true) {
            yield this.valueOf();
        }
    }
};

console.log(fibonacci); // 1
console.log(fibonacci); // 1
console.log(fibonacci); // 2

// Using it as an iterable
for (const value of fibonacci) {
    console.log(value); // 3, 5, 8, ...
    if (value >= 13) break; // Prevent infinite loop
}

The generator has been encapsulated, allowing it to be called like a variable.

The design of calling the Fibonacci variable itself generates side effects, allowing it to be used in the concept of "activation."