JavaScript Generators
Generators are a special kind of function in JavaScript that can be paused and resumed, allowing you to produce a sequence of values over time without creating an array to store them all at once. This makes them memory efficient for working with large datasets or infinite sequences.
Defining a Generator:
Generators are defined using an asterisk (*
) after the function
keyword or before the function name in arrow functions. They use the yield
keyword to return a value and pause execution.
function* myGenerator() {
yield 1;
yield 2;
yield 3;
}
const anotherGenerator = function* () {
yield 'a';
yield 'b';
yield 'c';
};
const arrowGenerator = *() => {
yield true;
yield false;
};
Using a Generator:
You interact with a generator through its iterator. Calling the generator function doesn’t execute its body. Instead, it returns an iterator object.
const gen = myGenerator();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }
Each call to next()
on the iterator resumes the generator, executes until the next yield
, and returns an object with the yielded value
and a done
flag indicating whether the generator has finished.
Iterating over a Generator:
You can easily iterate over a generator using a for...of
loop:
for (const value of myGenerator()) {
console.log(value); // 1, 2, 3
}
Example: Generating an Infinite Sequence:
Generators are excellent for representing infinite sequences because they generate values on demand.
function* infiniteCounter() {
let i = 0;
while (true) {
yield i++;
}
}
const counter = infiniteCounter();
console.log(counter.next().value); // 0
console.log(counter.next().value); // 1
console.log(counter.next().value); // 2
// ... and so on
Example: Generating Fibonacci Numbers:
function* fibonacci() {
let a = 0;
let b = 1;
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
const fib = fibonacci();
for (let i = 0; i < 10; i++) {
console.log(fib.next().value); // 0, 1, 1, 2, 3, 5, 8, 13, 21, 34
}
Generators provide a powerful and efficient way to work with sequences of data in JavaScript, especially when dealing with large datasets or infinite sequences. They are a valuable tool for any JavaScript developer to understand.