执行Generator函数会返回一个遍历器对象,可以一次遍历Generator函数内部的每一个状态。
形式上function关键字后跟一个 * ,函数内部使用yield表达式
function* gen() {
yield '123'
yield '456'
yield '789'
}
通过 next 方法会遍历到下一个内部状态。
如果函数中没有 return ,则next方法可以继续迭代下去,value值为undefined,done为true;反之将return 语句后面的表达式的值,作为返回的对象的value属性值,done为true。
done用来判断是否存在下个状态,value对应状态值。
const g1 = gen()
console.log(g1);
console.log(g1.next()); //{ value: '123', done: false }
console.log(g1.next()); //{ value: '456', done: false }
console.log(g1.next()); //{ value: '789', done: false }
console.log(g1.next()); //{ value: undefined, done: true }
通过调用 next 方法可以带一个参数,该参数就会被当作上一个 yield 表达式的返回值
function* ca(n) {
let a = yield (n + 5)
let b = yield (n + 10)
return a + b
}
const c1 = ca(3)
console.log(c1.next()); //{ value: 8, done: false }
console.log(c1.next(20));//{ value: 13, done: false }
console.log(c1.next(10));//{ value: 30, done: true }
//参数20和10分别做了两个yield的返回值 相当于 a = 20 b = 10
for ... of 是迭代器的语法糖
原生对象没有遍历接口,可以手动加上
function* objectEntries(obj) {
let propKeys = Reflect.ownKeys(obj);
for (let propKey of propKeys) {
yield [propKey, obj[propKey]];
}
}
let jane = { first: 'LIKO', last: 'best' };
for (let [key, value] of objectEntries(jane)) {
console.log(`${key}: ${value}`);
}
或者给对象写一个Symbol.iterator属性
let obj = {
minAge: 15,
age: 20,
[Symbol.iterator]() {
return {
minAge: this.minAge,
age: this.age,
next() {
if (this.minAge === this.age + 1) {
return {
value: undefined,
done: true
}
} else {
return {
value: this.minAge++,
done: false
}
}
}
}
}
}
for (let value of obj) {
console.log(value);
}