function asterisk

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"

原文地址