(1)语法说明:Generator函数其实是一个普通函数,其有两个特点,一是,function关键字与函数名之间有一个星号(*);二是Generator函数内部使用yield表达式,定义不同的状态,然后分段的去执行,如下:
function * helloWorld() {
yield "hello";
yield "world";
return "end";
}
// 说明:定义一个Generator函数helloWorld,此时Generator函数内部有两个yield和一个return,表示存在三个状态:即两个yield表达式和一个return语句(结束语句)
// 调用Generator函数,返回一个指向Generator函数内部状态的指针对象,即遍历器对象(Iterator Object)
let hw = helloWorld();
// 调用遍历器对象的next方法,使得指针指向下一个状态,下次调用的时候,从函数头部或者上次停下来的地方开始往下执行,直到遇到最后一个yield或者return语句为止,yield表达式是暂停执行标记,而next方法则是恢复执行标记;遍历器对象的next方法的返回值是一个对象,该对象的value属性的值就是yield表达式的值,done属性的值是一个Boolean值,表示遍历是否结束,
hw.next()
(2)yield表达式
遇到yield表达式,暂停执行,并将yield后面的表达式的值,作为返回的对象的value属性的值;如果有return语句,return的返回值也作为返回对象的value属性的值;如果没有return语句,则返回的对象的value属性值为undefined
/*
yield表达式与return语句的区别:
共同点:都能返回语句后面表达式的值。
区别:每次遇到yield表达式,函数暂停执行,需要调用遍历器对象的next方法才会继续往下执行,而下次从该位置继续往后执行,而return语句没有位置记忆功能,且一个函数里只能执行一次return语句;而一个Generator函数里可以有多个yield表达式。
*/
(3)next方法的参数
// 第一个next方法带参数没有意义,因为第一个next是用来启动遍历器对象的,所有不用带参数;从第二个next开始,next的参数表示上一个yield表达式的返回值
(4)for...of循环遍历器对象
for...of循环可以自动变量Generator函数生成的遍历器对象,此时不需要调用next方法了,直接返回yield的表达式结果
function *foo() {
yield 1;
yield 2;
yield 3;
yield 4;
yield 5;
return 6;
}
var hw = foo();
for (let item of hw) {
console.log(item); // 依次打印1 2 3 4 5
}
// 注意:使用for...of循环,一旦next方法返回的对象的done属性值为true,那么循环就会停止,for...of循环遇到return语句就立即停止,且只返回return语句之前的yield表达式值,return语句及return后面的yield表达式不会被返回。
// 在for...of循环之后再调用hw.next(),此时