var each = function (ary, callback) { for (let i = 0; i < ary.length; i++) { callback(ary[i], i); } };
each([1, 2, 3], function (item, index) { dosomething(item, index); });
内部迭代器和外部迭代器
内部迭代器
上面的 each 函数属于内部迭代器,each 函数的内部已经定义好了迭代规则,它完全接手整个迭代过程,外部只需要一次初始调用。
内部迭代器在调用的时候非常方便,外界不用关心迭代器内部的实现,跟迭代器的交互也仅仅是一次初始调用,但这也刚好是内部迭代器的缺点。由于内部迭代器的迭代规则已经被提前规定,上面的 each 函数就无法同时迭代 2 个数组了。
比如现在有个需求,要判断 2 个数组里元素的值是否完全相等, 如果不改写 each 函数本身 的代码,我们能够入手的地方似乎只剩下 each 的回调函数了,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12
var compare = function (ary1, ary2) { if (ary1.length !== ary2.length) { thrownewError("ary1 和 ary2 不相等"); } each(ary1, function (i, n) { if (n !== ary2[i]) { thrownewError("ary1 和 ary2 不相等"); } }); alert("ary1 和 ary2 相等"); }; compare([1, 2, 3], [1, 2, 4]); // throw new Error ( 'ary1和ary2不相等' );
外部迭代器
外部迭代器必须显式地请求迭代下一个元素,下面是一个外部迭代器的实现:
1 2 3 4 5 6 7 8 9 10 11
var Iterator = function (obj) { var current = 0; var getCurrItem = function () { return obj[current]; }; return { next: next, isDone: isDone, getCurrItem: getCurrItem, }; };
下面是 compare 函数的改写:
1 2 3 4 5 6 7 8 9 10 11 12 13
var compare = function (iterator1, iterator2) { while (!iterator1.isDone() && !iterator2.isDone()) { if (iterator1.getCurrItem() !== iterator2.getCurrItem()) { thrownewError("iterator1 和 iterator2 不相等"); } iterator1.next(); iterator2.next(); } alert("iterator1 和 iterator2 相等"); }; var iterator1 = Iterator([1, 2, 3]); var iterator2 = Iterator([1, 2, 3]); compare(iterator1, iterator2); // 输出:iterator1 和 iterator2 相等