function*声明(function
关键字加上一个星号)定义一个生成器函数,返回一个生成器(Generator)对象.
你还可以通过GeneratorFunction构造函数以及function* expression来定义生成器函数.
语法
function* name([param[, param[, ... param]]]) {
statements
}
name
函数的名字
param
传递给函数的参数的名字.一个函数最多可以带有255个参数.
statements
statements由函数体组成.
描述
Generators 是可以退出和再次进入的函数.它的上下文(变量的绑定)在整个重新进入的过程中一直会被保存.
调用一个generator函数,并不会立刻执行函数体;而是返回一个函数的迭代器(iterator).
每当调用迭代器的 next()
方法时,generator的函数体就会被执行,直到它遇到第一个yield表达式. 它指定了迭代器的返回值,如果使用 yield*,则代理到另一个generator函数. next()
方法返回一个对象,对象的 value
属性的值是 yield
表达式的值; done
属性的值表明该generator是否已经执行完了全部的yield. 详见Generator.prototype.next().
当调用迭代器的 return(param)
方法时,Generator被关闭,返回参数 param
的值,详见 Generator.prototype.return()
栗子
简单的栗子
function* idMaker(){
var index = 0;
while(index < 3)
yield index++;
}
var gen = idMaker();
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().done); // false
console.log(gen.next().value); // 2
console.log(gen.next().done); // true
console.log(gen.next().value); // undefined
使用 yield*
的栗子
function* anotherGenerator(i) {
yield i + 1;
yield i + 2;
yield i + 3;
}
function* generator(i){
yield i;
yield* anotherGenerator(i);
yield i + 10;
}
var gen = generator(10);
console.log(gen.next().value); // 10
console.log(gen.next().value); // 11
console.log(gen.next().value); // 12
console.log(gen.next().value); // 13
console.log(gen.next().value); // 20
这里需要注意,使用yield*返回的代理迭代器拥有自己的闭包环境,两个i不是同一个i,如果把另一个参数换成a,可能更清晰一点…
生成器不是构造函数
下面这样做是不行的:
function* f() {}
var obj = new f; // throws "TypeError: f is not a constructor"