ES6中的generator
返回一个iterator/iterable
,由“function*
”定义,
generator
返回的对象,既可以看做一个iterator
,也可以看做是一个iterable
var iterator = {
// iterator
next: v => ({ value: xxx, done: xxx }),
// iterable
[Symbol.iterator]: () => iterator
};
iterator[Symbol.iterator]() === iterator
例如:
function* gen() {
yield 1;
yield 2;
yield 3;
}
var i = gen();
// 把i视为iterator的例子
console.log(i.next().value); //1
console.log(i.next().value); //2
console.log(i.next().value); //3
i = gen();
// 把i视为iterable的例子
console.log(...i); //1 2 3
注意:
(1)作为对象属性的generator
可以简写
var obj = {
* generatorMethod() {
}
};
// 等价于
let obj = {
generatorMethod: function *() {
}
};
(2)考虑到generator
可以视为返回了一个iterator
,
所以可以让obj
的Symbol.iterator
方法是一个generator
,
则obj
就是一个iterable
了。
var obj={
* [Symbol.iterator](){
yield 1;
yield 2;
yield 3;
}
};
分析:因为obj的Symbol.iterator
方法是一个generator
,
调用后返回一个iterator
,
所以,obj
是一个iterable
。
console.log(...obj); //1 2 3
(3)generator
返回的iterator
,它的next
方法返回一个形如{ value:xxx, done:xxx }
的对象
generator
中可以包含return
,如果不写return
,则末尾自动包含return
。
(其中,return;
相当于return undefined;
如果next
是yield
返回的,则done===false
,value
就是yield
后面的值,
如果next
是return
返回的,则done===true
,value
就是return
后面的值
如果已经是done===true
,则再次调用iterator.next()
并不会出错,
而是返回{done:true, value:undefined}
,注意这里value
是undefined
。
(4)iterator.next
是可以带参数的
第一次调用iterator.next(v)
,参数v
将会丢弃,
后面每次调用iterator.next(v)
,参数v
就变成了上一个yield
的�返回值。
function* gen() {
var v1=yield 1;
console.warn(v1);
var v2=yield 2;
console.warn(v2);
var v3=yield 3;
console.warn(v3);
return 4;
}
var i = gen();
//iterator
console.log(i.next('a')); //{done:false,value:1}
console.log(i.next('b')); //v1='b', {done:false,value:2}
console.log(i.next('c')); //v2='c', {done:false,value:3}
console.log(i.next('d')); //v3='d', {done:true,value:4}
console.log(i.next('e')); //{done:true,value:undefined}
console.log(i.next('f')); //{done:true,value:undefined}