定义迭代器(Iterator)
迭代器是一个特殊对象:
- 含有
next()
方法,返回一个对象{value:...,done:false}
,value
表示下一个要返回的值,done
表示后续是否还有值。当迭代到最后一个位置时,后续调用next
方法会返回{value:undefined,done:true}
- 有一个内部指针,指向当前集合中值的位置。
我们可以尝试自己模拟一个迭代器:
function createIterator(items){
let i = 0;
return {
next(){
const done = (i>=items.length);
const value = done ? undefined : items[i];
i++;
return { done, value }
}
}
}
var iterator = createIterator([1,2,3]);
console.log(iterator.next()); // {value:1,done:false}
console.log(iterator.next()); // {value:2,done:false}
console.log(iterator.next()); // {value:3,done:false}
console.log(iterator.next()); // {value:undefined,done:true}
console.log(iterator.next()); // {value:undefined,done:true}
但其实不需要我们去模拟一个生成迭代器的函数,es6同时也为我们提供给了生成迭代器的函数 —— 生成器。
定义生成器(Generator)
生成器是返回迭代器的函数:
- 声明时要在
function
关键字后加上星号*
来表示这是一个生成器 - 函数中间会用到关键字
yield
,可以通过它来指定调用迭代器的next()
方法后的返回值。不能在生成器以外使用yield
关键字。 - 不能用箭头函数创建生成器。
我们可以看一下如何使用生成器生成迭代器:
function * createIterator(){
yield 1;
yield 2;
yield 3;
}
// 连续调用3次next方法,分别返回1,2,3
var iterator = createIterator();
这样声明的 createIterator
生成器,和我们在上面模拟出来的 createIterator
方法,效果基本一致,对于生成的 iterator
,就是一个具有 next
方法的迭代器。当然,我们要是传入一个数组,完全可以写成下面的形式:
// 用函数表达式创建生成器的写法
let createIterator = function * (items){
for(let i=0;i<items.length;i++){
yield items[i];
}
}
var iterator = createIterator([1,2,3]);
在生成器中,每当执行一条 yield 语句后函数就会自动停止执行,直到再次调用迭代器的 next() 方法。