The effect of your code is like this:
for (let x of gen1()) console.log(x) // "1"
for (let x of gen2()) console.log(x) // "function* gen1() { yield 1; }"
for (let x of gen3()) console.log(x) // throws TypeError
What you probably meant was:
var gen2 = function* () {
yield gen1();
};
var gen3 = function* () {
yield* gen1();
};
In that case you get:
for (let x of gen2()) console.log(x) // "[object Object]"
for (let x of gen3()) console.log(x) // "1"
That is, a plain yield
just returns whatever the operand expression evaluates to (in the case of gen2
, an unused iterator object). A yield*
on the other hand delegates to another iterator. It will yield whatever that iterator yields, until it is exhausted. More concretely:
function* g() { yield 1; yield 2; yield 3 }
function* h() { yield 4; yield* g(); yield 5 }
function* i() { yield 6; yield* h(); yield 7 }
for (let x of i()) console.log(x) // 6, 4, 1, 2, 3, 5, 7