There is such a thing as generator functions in JavaScript and they let you define functions that return Generator objects. The syntax for defining a generator function is nearly the same as for defining a regular function.
function* makeIterator() {
yield 1
}
Note the use of function*
(the added asterisk) and the yield
keyword. Calling makeIterator()
will return a Generator object. Generator objects are iterable objects similar to Array and Map objects. They can be looped over easily using the for ... of
syntax, for example.
Iterating over an iterator is said to consume the iterator because it is generally only possible to do once. - MDN
More Examples
In this example, the defined generator function allows for defining ranges. Calling the Generator object's next()
function returns an object with two properties: value
and done
.
function* range(start, end) {
for (let i = start; i <= end; i++) {
yield i;
}
}
let myRange = range(1, 3)
console.log(myRange.next()) // { value: 1, done: false }
console.log(myRange.next()) // { value: 2, done: false }
console.log(myRange.next()) // { value: 3, done: false }
console.log(myRange.next()) // { value: undefined, done: true}
The range can be immense (even Infinity) but won't allocate space for every value that the range represents. Also, the generator is lazily evaluated - meaning there is no execution cost if the values are never needed.
// These have identical memory and execution costs.
let rangeA = range(1, 3)
let rangeB = range(1, Infinity)
Use Cases
There are probably many amazing use cases for generators. But one that interests me specifically is generating repeating reminders/scheduled events that potentially continue indefinitely.