迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。不关心对象的内部构造,可以按顺序访问其中的每个元素。
内置迭代器
如:forEach Iterator等,再如jquery的$.each / for...of
定义:内部已经定义好了迭代规则,它完全接手整个迭代过程,外部只需要一次初始调用;迭代器模式的核心,就是实现统一遍历接口。
实现
var each = function(arr, callBack) { // 统一遍历接口实现
for (let i = 0, len = arr.length; i < len; i++) { // 将值,索引返回给回调函数callBack处理
if (callBack(i, arr[i]) === false) {
break; // 中止迭代器,跳出循环
}
}
}
each([1, 2, 3, 4, 5], function(index, value) { // 外部调用
if (value > 3) {
return false; // 返回false中止each
}
console.log([index, value]);
}) // 输出:[0, 1] [1, 2] [2, 3]
优缺点
优点:内部迭代器在调用时非常方便,外界不用关心迭代器内部的实现,跟迭代器的交互也仅仅是一次初始调用
缺点:由于内部迭代器的迭代规则已经被提前规定,上面的 each 函数就无法同时迭代2个数组,如下代码
var compare = function( ary1, ary2 ){
if ( ary1.length !== ary2.length ){
throw new Error ( 'ary1 和ary2 不相等' );
}
each( ary1, function( i, n ){
if ( n !== ary2[ i ] ){
throw new Error ( 'ary1 和ary2 不相等' );
}
});
alert ( 'ary1 和ary2 相等' );
};
compare( [ 1, 2, 3 ], [ 1, 2, 4 ] ); // throw new Error ( 'ary1 和ary2 不相等' );
外部迭代器
如:ES6 的 yield
定义:外部迭代器必须显式地请求迭代下一个元素
实现
我们模拟一个es6迭代器
var Iterator = function (ary) {
this.ary = ary
this.index = 0
}
Iterator.prototype.isDone = function () {
return this.index >= this.ary.length
}
Iterator.prototype.next = function () {
if (!this.isDone()) {
var res = this.ary[this.index]
this.index++
return {
value: res,
done: this.isDone()
}
}
}
var a = new Iterator([1, 2, 3])
while (!a.isDone()) {
console.log(a.next())
}
下面解决一下上面那个问题
var a = new Iterator([1, 2, 3, 3])
var b = new Iterator([1, 2, 3])
function compare(iterator1, iterator2) {
while (!iterator1.isDone() || !iterator2.isDone()) {
if (iterator1.next().value !== iterator2.next().value) {
return false
}
}
return true
}
compare(a, b)
优点:灵活性更佳,适用面广,能应对更加复杂的迭代需求
缺点:需显示调用迭代进行(手动控制迭代过程),外部调用方式较复杂
网友评论