ES6总结之Generator
Contents
Generator函数定义
function
关键字与函数名之间有一个*
号- 函数体内部使用
yield
表达式,定义不同的内部状态
调用Generator
函数时,实际上并不会执行,而是返回一个指向内部状态的对象。
通过执行Generator
函数的next
方法,来遍历函数内部的状态,同时使内部指针移向下一个状态(yield
表达式)
function* helloWorldGenerator() {
yield 'hello';
yield 'world';
return 'ending';
}
var hw = helloWorldGenerator();
hw.next()
// { value: 'hello', done: false }
hw.next()
// { value: 'world', done: false }
hw.next()
// { value: 'ending', done: true }
hw.next()
// { value: undefined, done: true }
next方法和yield表达式
yield
表达式表示暂停,返回一个包含value
和done
的对象。value
为yield
表达式的值,done
表示是否遍历结束
没调用一次next
方法,执行到yield
表达式为止。如果没有再遇到新的yield
表达式,就一直运行到函数结束,直到return
语句为止,并将return
语句后面的表达式的值,作为返回的对象的value
属性值。如果该函数没有return
语句,则返回的对象的value
属性值是undefined
带参数的next方法
yield
表达式本身返回undefined
。next
方法的参数会被当成上一个yield
表达式的的返回值
function* foo(x) {
var y = 2 * (yield (x + 1));
var z = yield (y / 3);
return (x + y + z);
}
var a = foo(5);
a.next() // Object{value:6, done:false}
a.next() // Object{value:NaN, done:false}
a.next() // Object{value:NaN, done:true}
var b = foo(5);
b.next() // { value:6, done:false }
b.next(12) // { value:8, done:false }
b.next(13) // { value:42, done:true }
第一个a.next()
,到yield(x + 1)
暂停,值为6
第二个a.next()
,到yield(y /3)
暂停,next不带参数,上一个yield表达式的值(yield(x + 1)
为undefined
),所以值为NaN
第三个a.next()
,z为undefined
的,值为NaN
第一个b.next()
,到yield(x + 1)
暂停,值为6
第二个b.next(12)
,到yield(y /3)
暂停,next带参数,上一个yield表达式的值(yield(x + 1)
为12
),y = 24
所以值为8
第三个b.next(13)
,到return (x + y + z)
暂停,next带参数,上一个yield表达式的值(yield((y /3)
为13
),y = 24, z = 13
值为42
for of 循环
for…of循环可以自动遍历Generator
函数时生成的Iterator
对象,但不会返回done
属性为 true
的对象
yield* 表达式
function* inner() {
yield 'hello!';
}
function* outer1() {
yield 'open';
yield inner();
yield 'close';
}
var gen = outer1()
gen.next().value // "open"
gen.next().value // 返回一个遍历器对象
gen.next().value // "close"
function* outer2() {
yield 'open'
yield* inner()
yield 'close'
yield ['a','b','c']
yield* ['a','b','c']
}
var gen = outer2()
gen.next().value // "open"
gen.next().value // "hello!"
gen.next().value // "close"
gen.next().value // 数组对象
gen.next().value // "a"
使用了yield*
后,返回遍历器对象(或数组)的内部值。