迭代器: Iterator
迭代器的作用是为了方便遍历集合等数据结构, 如Array, Map, Set
所有的迭代器对象都带有一个next()
方法, 它返回一个包含两个属性的结果对象
- 一个是value, 表示下一个结果的值
- 一个是done, 标记迭代是否结束
return {
value,
done
}
迭代器的实现原理
var createIterator = function(items) {
var i = 0
return {
next: function() {
var done = (i >= items.length)
var value = !done ? items[i++] : undefined
return {
value: value,
done: done
}
}
}
}
var arr = createIterator([1, 2, 3])
console.log(arr.next()) // "{ value: 1, done: false }"
console.log(arr.next()) // "{ value: 2, done: false }"
console.log(arr.next()) // "{ value: 3, done: false }"
console.log(arr.next()) // "{ value: undefined, done: true }"
这里通过定义一个 i 指针, 利用闭包的原理, i 指针来一次次的指向下一个对象
在es6中的for...of
循环就是通过迭代器实现的
像常用的Array, String, Map, Set
都具备了Iterator
接口, 所以不用任何处理就能使用for...of
循环来遍历
var arr = [1, 2, 3, 4]
for (var i of arr) {
console.log(i)
}
// 1, 2, 3, 4
生成器: generator
生成器(generator)是一个能返回迭代器的函数, 在function
关键字后加一个*
号, 这个函数就成为了生成器函数
生成器函数中能使用yield
关键字, 它决定了迭代器
使用next()
方法时值返回的顺序
// 生成器
function *createIterator() {
yield 1;
yield 2;
yield 3;
}
// 生成器能像正规函数那样被调用,但会返回一个迭代器
let iterator = createIterator();
console.log(iterator.next().value); // 1
console.log(iterator.next().value); // 2
console.log(iterator.next().value); // 3
yield
关键字可用于值或表达式
// 例如这样
function *createIterator(items) {
for (let i = 0; i < items.length; i++) {
yield items[i];
// 也可以这样 yield items[i] + 1
}
}
生成器最有意思的特性是它能够暂停代码, 它们会在每个 yield
语句后停止执行, 直到迭代器的next
方法被再次调用
生成器的异步运行
由于生成器能在执行过程中有效地暂停代码操作,它就给异步编程带来了许多可能性。