I'm trying to have a better understanding of how generators work in javascript.
From MDN:
The function* declaration (function keyword followed by an asterisk) defines a generator function, which returns a Generator object.
function *range(from, to) {
var counter = from;
while(to >= counter) {
yield counter
counter++
}
}
for (var r of range(5, 10)) {
console.log( r );
}
// print: 5, 6, 7, 8, 9, 10
I'm not sure how I understand exactly what's happening in the snippet above.
Aren't generators supposed to be called, stored as (generator) objects and then called by the next()
method. (like below)
function *foo () {
yield 'woo';
}
var G = foo();
console.log( G.next() );
In the code above, on line 4 with var G = foo();
I am not calling a function and creating new execution context, this should just return a generator object (and store it under the label G
).
I'll invoke the actual function foo
, when I call the next()
method on it, on line 5. At that point, I'm creating an execution context, executing the code inside foo
and yielding out the string "woo"
.
How the first snippet is exactly supposed to work?
Calling a generator function will return an iterator (the object with a .next
function), and a for..of
loop will automatically iterate over iterable objects. While you can store the iterator in a variable beforehand:
const iter = range(5, 10);
for (var r of iter) {
...
}
it's not necessary - the for..of
only needs a single reference to an iterator, after all.
You could imitate this in code by passing a single reference to an iterator into a function that calls each .next
function until the iterator is exhausted:
function *range(from, to) {
var counter = from;
while(to >= counter) {
yield counter
counter++
}
}
iterate(range(5, 10), num => {
console.log(num);
});
function iterate(iterator, callback) {
while (true) {
const { value, done } = iterator.next();
if (done) return;
callback(value);
}
}
As you can see, there's no need to store the iterator in a variable before passing it to iterate
, just like you can use the range(5, 10)
call directly to a for..of
loop, because the loop (or function)'s internals do all the iteration for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With