最近在学ES6的知识,发现了一个很有趣,很神奇的东西,Generator函数。
写一个最简单的Generator函数,定义的时候比普通的函数多了一个*,然后使用yield和return向外输出信息。
调用的时候,先要执行Generator函数,例如var g1 = gen1(),这样,就会返回一个遍历器对象(Iterator Object),然后调用next()。
function* gen1() { yield 'hello'; yield 'world'; return '!!!'; } var g1 = gen1(); g1.next() //Object {value: "hello", done: false} g1.next() //Object {value: "world", done: false} g1.next() //Object {value: "!!!", done: true} g1.next() //Object {value: undefined, done: true}
每次调用next(),都会返回一个对象,value代表返回的值,done表示是否还能继续遍历。done为false表示还可以继续调用next(),为true,表示已经没有值可以返回了。比如第4个next(),value就为undefined
可见Generator函数是分段执行的,每次next()后都会暂停起来,等待下次next()
其实,生成遍历器对象(Iterator Object)的时候,还可以传递参数,比如
function* gen2(x){ yield x + 2; } var g2=gen2(5); g2.next(); //Object { value: 7, done: false } g2.next(); //Object { value: undefined, done: true }
看代码,很容易理解哈,和正常的函数传递参数效果一样哈
那现在来点不容易理解的,将上面的代码稍微改改,看代码
function* gen3(x){ var y = yield x + 2; var z = yield y; return z; } var g3=gen3(5); g3.next(); //Object { value: 7, done: false } g3.next(20); //Object { value: 20, done: false } g3.next(); //Object { value: undefined, done: true }
怎么样,看明白了么。为什么g3.next(20)输出的值是20呢?
按道理,g3.next(20)应该是yield y输出的,y应该和yield x+2有关系,应该是7才对呀
其实吧,var y = yield x + 2;,这里的y的值,并不取决于等号后面的值是多少,而是取决于下次调用next()传递的参数
因为第二次调用g3.next(20);传递的是20,所以,y的值就成了20,如果这里没有传值,那么就是undefined,就类似第3次调用next()
我当时也是这里看的有点疑惑,然后动手做了几个例子,加深理解,然后记录下来