// function* generatorFn() { 
// for (const x of [1, 2, 3]) { 
// yield x; 
// } 
// } 
function* generatorFn() { 
 yield* [1, 2, 3]; 
} 
let generatorObject = generatorFn(); 
for (const x of generatorFn()) { 
 console.log(x); 
} 
// 1 
// 2 
// 3

与生成器函数的星号类似,yield 星号两侧的空格不影响其行为:

yield* [1, 2]; 
 yield *[3, 4]; 
 yield * [5, 6]; 
} 
for (const x of generatorFn()) { 
 console.log(x); 
} 
// 1 
// 2 
// 3 
// 4 
// 5 
// 6

因为 yield*实际上只是将一个可迭代对象序列化为一连串可以单独产出的值,所以这跟把 yield 放到一个循环里没什么不同。下面两个生成器函数的行为是等价的:

for (const x of [1, 2, 3]) { 
 yield x; 
 } 
} 
for (const x of generatorFnA()) { 
 console.log(x); 
} 
// 1 
// 2 
// 3 
function* generatorFnB() { 
 yield* [1, 2, 3]; 
} 
for (const x of generatorFnB()) { 
 console.log(x);

// 1 // 2 // 3

undefined:
function* generatorFn() { 
 console.log('iter value:', yield* [1, 2, 3]); 
} 
for (const x of generatorFn()) { 
 console.log('value:', x); 
} 
// value: 1 
// value: 2 
// value: 3 
// iter value: undefined

对于生成器函数产生的迭代器来说,这个值就是生成器函数返回的值:

yield 'foo'; 
 return 'bar'; 
} 
function* outerGeneratorFn(genObj) { 
 console.log('iter value:', yield* innerGeneratorFn()); 
} 
for (const x of outerGeneratorFn()) { 
 console.log('value:', x); 
} 
// value: foo 
// iter value: bar
  1. 使用 yield实现递归算法 yield最有用的地方是实现递归操作,此时生成器可以产生自身。看下面的例子:
if (n > 0) { 
 yield* nTimes(n - 1); 
 yield n - 1; 
 } 
} 
for (const x of nTimes(3)) { 
 console.log(x); 
} 
// 0 
// 1 
// 2

在这个例子中,每个生成器首先都会从新创建的生成器对象产出每个值,然后再产出一个整数。结 果就是生成器函数会递归地减少计数器值,并实例化另一个生成器对象。从最顶层来看,这就相当于创 建一个可迭代对象并返回递增的整数。 使用递归生成器结构和 yield*可以优雅地表达递归算法。下面是一个图的实现,用于生成一个随 机的双向图: