Generators and yield*

A generator object (Generators) is both an iterator and an iterable. Inside a generator, yield* iterable forwards every value of another iterable and evaluates to that generator's return value, which spread and for...of discard. A generator that delegates to itself walks recursive structures such as DOM trees.

Recursive traversal and the value of yield*JavaScriptLive
function* walk(node, depth = 0) {               // recursion through yield*
  yield '-'.repeat(depth) + node.v;
  for (const kid of node.kids ?? []) yield* walk(kid, depth + 1);
}
const tree = { v: 'html', kids: [{ v: 'head' }, { v: 'body', kids: [{ v: 'p' }] }] };
console.log([...walk(tree)]);
function* inner() { yield* 'ok'; return 42; }   // a string is iterable too
function* outer() { const result = yield* inner(); yield result; }
console.log([...inner()], [...outer()]);

Each next() passes through every level of a yield* chain, so for very deep trees an explicit stack is faster.