function 想必大家都熟烂于心,那什么是 function* 呢?function* 就是上面提到的生成器函数。我们来看个例子,在 Node 的 REPL 中运行:
function* helloWorldGeneratorFunction() {
yield 'hello';
yield 'world';
return '!';
}
var helloWorldGenerator = helloWorldGeneratorFunction();
> helloWorldGenerator.next()
{ value: 'hello', done: false }
> helloWorldGenerator.next()
{ value: 'world', done: false }
> helloWorldGenerator.next()
{ value: '!', done: true }
> helloWorldGenerator.next()
{ value: undefined, done: true }
有几点需要说明:
稍微改一下上面的例子:
function* helloWorldGeneratorFunction() {
var hello = yield 'hello';
console.log(hello);
var world = yield 'world';
console.log(world);
return '!';
}
var helloWorldGenerator = helloWorldGeneratorFunction();
> helloWorldGenerator.next()
{ value: 'hello', done: false }
> helloWorldGenerator.next()
undefined
{ value: 'world', done: false }
> helloWorldGenerator.next()
undefined
{ value: '!', done: true }
> helloWorldGenerator.next()
{ value: undefined, done: true }
上例中,当第一次调用生成器的 next 方法时,函数执行到 yield 'hello'
,会返回 { value: 'hello', done: false }
,但此时 yield 没有返回值,或者说返回值为 undefined,所以当下一次调用 next 方法时,相当于执行 var hello = undefined; console.log(hello); yield 'world'
。所以 console.log(hello); 会打印 undefined,同理 console.log(world); 也会打印 undefined。
再稍微修改一下上面的例子,在 next 方法中传入参数:
function* helloWorldGeneratorFunction() {
var hello = yield 'hello';
console.log(hello);
var world = yield 'world';
console.log(world);
return '!';
}
var helloWorldGenerator = helloWorldGeneratorFunction();
> helloWorldGenerator.next(1)
{ value: 'hello', done: false }
> helloWorldGenerator.next(2)
2
{ value: 'world', done: false }
> helloWorldGenerator.next(3)
3
{ value: '!', done: true }
> helloWorldGenerator.next(4)
{ value: undefined, done: true }
我们往 next 方法里传入了参数,那么该参数就成为上一个 yield 语句的返回值。即上例中调用 helloWorldGenerator.next(2)
相当于执行了 var hello = 2; console.log(hello); yield 'world'
。由于 next 方法的参数当作了上一个 yield 语句的返回值,所以第一次调用 next 方法时传入的参数将被忽略。
生成器函数也是函数,所以拥有所有函数的特性。比如作用域,闭包,遇到第一个 return 会执行结束等等。生成器函数又有些普通函数没有的特性,如可以使用 yield 并且 yield 只能在生成器函数内使用,如果在普通函数内使用 yield 将会报错。