javascript 高级编程系列 - 生成器函数迭代器参数区别
生成器函数(Generator Function)执行后返回一个迭代器。当我们调用这个迭代器的 next() 方法时,是否传入参数有着本质的区别:
核心结论
- 不传参数:
yield表达式返回undefined,生成器从上次暂停的位置继续执行。 - 传参数:传入的参数会成为上一个
yield表达式(即暂停点)的返回值,生成器从这个位置继续执行。
简单记法:next(value) 是“喂”给生成器的值,它作为上一个 yield 的返回值。
1. 不传参数的情况
function* gen() {
const a = yield 1;
console.log('a =', a);
const b = yield 2;
console.log('b =', b);
return 3;
}
const it = gen();
console.log(it.next()); // { value: 1, done: false }
console.log(it.next()); // a = undefined
// { value: 2, done: false }
console.log(it.next()); // b = undefined
// { value: 3, done: true }
- 第一个
next():执行到yield 1,暂停,返回1。 - 第二个
next():从上个暂停点恢复,yield 1这个表达式的结果是undefined,赋值给a。然后继续到yield 2,返回2。 - 第三个
next():yield 2的结果是undefined,赋值给b。最后return 3。
2. 传参数的情况
function* gen() {
const a = yield 1;
console.log('a =', a);
const b = yield 2;
console.log('b =', b);
return 3;
}
const it = gen();
console.log(it.next()); // { value: 1, done: false }
console.log(it.next('hello')); // a = hello
// { value: 2, done: false }
console.log(it.next('world')); // b = world
// { value: 3, done: true }
- 第一个
next():无法传参(因为还没有遇到 yield),参数被忽略。 - 第二个
next('hello'):'hello'成为上一个 yield(yield 1)的返回值,赋值给a。 - 第三个
next('world'):'world'成为上一个 yield(yield 2)的返回值,赋值给b。
3. 第一个 next() 的特殊性
第一个 next() 不能传参生效,因为此时生成器还没有执行到任何 yield 表达式。
function* gen() {
const x = yield 10;
console.log(x);
}
const it = gen();
it.next('test'); // 参数 'test' 被忽略
it.next(); // x = undefined
如果想要在生成器启动时传递初始值,应该通过生成器函数的参数:
function* gen(initial) {
console.log('initial =', initial);
yield initial + 1;
}
const it = gen(100);
it.next(); // initial = 100, { value: 101, done: false }
4. 为什么需要这种设计?
这种机制让生成器可以和外部进行双向通信:
function* ask() {
const name = yield '你叫什么名字?';
const age = yield `你好 ${name},你多大了?`;
return `${name} 今年 ${age} 岁。`;
}
const it = ask();
console.log(it.next().value); // 你叫什么名字?
console.log(it.next('小明').value); // 你好 小明,你多大了?
console.log(it.next(18).value); // 小明 今年 18 岁。
- 生成器向外部“询问”信息
- 外部通过
next()参数“回答”问题
5. 一个容易混淆的点
next(value) 的参数不是当前 yield 的返回值,而是上一个 yield 的返回值。
function* demo() {
console.log('开始');
const x = yield 1; // ← 这个 yield 的值由下一次 next() 提供
console.log('x =', x);
yield 2;
}
const it = demo();
it.next(); // 输出: 开始
// 返回: { value: 1, done: false }
it.next(100); // 输出: x = 100
// 返回: { value: 2, done: false }
时间线:
- 第一次
next():执行到yield 1,暂停,返回1 - 第二次
next(100):从暂停点恢复,yield 1这个表达式得到值100→ 赋值给x
总结对比表
| 调用方式 | 作用 | 第一个 next() 是否有效 |
|---|---|---|
next() |
恢复执行,上一个 yield 返回 undefined |
✅ 可调用,参数无效 |
next(value) |
恢复执行,上一个 yield 返回 value |
❌ 参数被忽略 |
核心记忆点:
yield就像向外部请求一个值next(value)就是外部给这个请求的回应

浙公网安备 33010602011771号