迭代器模式定义
迭代器(Iterator)模式,又叫做游标(Cursor)模式。它提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。迭代器模式可以把迭代的过程从业务逻辑中分离出来,在使用迭代器模式之后,即使不关心对象的内部构造,也可以按顺序访问其中的每个元素。
迭代器模式的优缺点
迭代器模式的优点:
简化了遍历方式,对于对象集合的遍历,还是比较麻烦的,对于数组或者有序列表,
我们尚可以通过游标取得,但用户需要在对集合了解的前提下,自行遍历对象,
但是对于 hash 表来说,用户遍历起来就比较麻烦。而引入迭代器方法后,用户用起来就简单的多了。
封装性良好,用户只需要得到迭代器就可以遍历,而不用去关心遍历算法。
迭代器模式的缺点:
遍历过程是一个单向且不可逆的遍历
ES 迭代器
在 ECMAScript 中 Iterator 最早其实是要采用类似 Python 的 Iterator 规范,就是 Iterator 在没有元素之后
,执行 next 会直接抛出错误;但后来经过一段时间讨论后,决定采更 functional 的做法,改成在取得最后一个元素之后执行 next 永远都回传 { done: true, value: undefined }
一个迭代器对象 ,知道如何每次访问集合中的一项, 并记录它的当前在序列中所在的位置。在 JavaScript 中迭代器是一个对象,它提供了一个 next() 方法,返回序列中的下一项。这个方法返回包含 done 和 value 两个属性的对象。对象的取值如下:
在最后一个元素前:{ done: false, value: elementValue }
在最后一个元素后:{ done: true, value: undefined }
详细信息可以参考 - 可迭代协议和迭代器协议
ES 5 迭代器
接下来我们来创建一个 makeIterator 函数,该函数的参数类型是数组,当调用该函数后,返回一个包含 next() 方法的 Iterator 对象, 其中 next() 方法是用来获取容器对象中下一个元素。具体示例如下:
function makeIterator(array){
var nextIndex = 0;
return {
next: function(){
return nextIndex < array.length ?
{value: array[nextIndex++], done: false} :
{done: true};
}
}
}
一旦初始化, next() 方法可以用来依次访问可迭代对象中的元素:
var it = makeIterator([‘yo’, ‘ya’]);
console.log(it.next().value); // ‘yo’
console.log(it.next().value); // ‘ya’
console.log(it.next().done); // true
ES 6 迭代器
在 ES 6 中我们可以通过 Symbol.iterator 来创建可迭代对象的内部迭代器,具体示例如下:
let arr = [‘a’, ‘b’, ‘c’];
let iter = arrSymbol.iterator;
调用 next() 方法来获取数组中的元素:
iter.next()
{ value: ‘a’, done: false }
iter.next()
{ value: ‘b’, done: false }
iter.next()
{ value: ‘c’, done: false }
iter.next()
{ value: undefined, done: true }
ES 6 中可迭代的对象:
Arrays
Strings
Maps
Sets
DOM data structures (work in progress)