В чём разница между этими фрагментами кода? yield *smth for (let x of smth) { yield x } @torazaburo в комментарии сказал This is an OK simplification, but it fails to address what the yield *generator() evaluates to, which as it turns out is the end-of-iteration value return'ed by the generator object. It also does not correctly represent what happens when the consumer of the generator throws into the generator, etc. Хотелось бы узнать, в чём именно заключается разница и в каких случаях она проявит себя.
Ответ На самом деле, синтаксис yield * gen используется для передачи управления внутрь другого генератора. Вот что об этом говорит MDN: The yield* expression iterates over the operand and yields each value returned by it. А вот и пример того, как это работает: let seqPos = function * (max) { for (let i = 1 i <= max i++) { yield i } }<br>let seqNeg = function * (min) { let start = min > 0 ? -1*min : min for (let i = start i < 0 i++) { yield i } } let seq = function * (val) { yield * seqNeg(-1*val) yield 0 yield * seqPos(val) } for (let i of seq(2)) { console.log(i) } Пример выше выведет: -2 -1 0 1 2 А вот и JSFiddle с примером.
Что касается основного вопроса, то разница между конструкциями: for (let val of gen) { yield val } и yield * gen заключается в том, что в первом случае всего лишь возвращаются значения дочернего генератора, а во втором управление полностью передается дочернему генератору. Это значит, что вызов методов Generator.prototype.next, Generator.prototype.throw и Generator.prototype.return клиентским кодом на родительском генераторе будет адресован дочернему генератору: let innerGen = function * () { try { for (let i = 0 i < 3 i++) { console.log(yield i) } } catch (e) { console.log('Got you!') } } let outerGen = function * () { let child = innerGen() yield * child } let g = outerGen() g.next() g.next("foo") // выведет в консоль "foo" g.throw(new Error('Oops!')) // выведет "Got you!" Ситуация, с пробросом исключений в дочерний итератор, описанная участником @Роман Парадеев в соседнем ответе, является всего лишь частным случаем передачи управления дочернему генератору.