Appearance
迭代器的分类
迭代器可以分为内部迭代器和外部迭代器,它们有各自的适用场景。
内部迭代器
刚刚编写的 each 函数属于内部迭代器,内部迭代器在调用的时候非常方便,外界不用关心迭 代器内部的实现,跟迭代器的交互也仅仅是一次初始调用,但这也刚好是内部迭代器的缺点。 由于内部迭代器的迭代规则已经被提前规定,上面的 each 函数就无法同时迭代 2 个数组了。
比如现在有个需求,要判断 2 个数组里元素的值是否完全相等,如果不改写 each 函数本身 的代码,我们能够入手的地方似乎只剩下 each 的回调函数了。
javascriptconst compare = function(ary1, ary2){ if (ary1.length !== ary2.length){ throw new Error ('ary1 和 ary2 不相等') } each(ary1, function(i, v){ if (v !== ary2[i]){ throw new Error ('ary1 和 ary2 不相等') } }) alert ('ary1 和 ary2 相等') }外部迭代器
外部迭代器必须显式地请求迭代下一个元素。外部迭代器增加了一些调用的复杂度,但相对也增 强了迭代器的灵活性,我们可以手工控制迭代的过程或者顺序。
javascriptconst Iterator = function(obj){ const current = 0 const next = function () { current += 1 } const isDone = function () { return current >= obj.length } const getCurrItem = function () { return obj[current] } return { next, isDone, getCurrItem } }再看看如何改写 compare 函数:
javascriptconst compare = function (iterator1, iterator2) { while(!iterator1.isDone() && !iterator2.isDone()) { if (iterator1.getCurrItem() !== iterator2.getCurrItem()) { throw new Error ( 'iterator1 和 iterator2 不相等' ) } iterator1.next() iterator2.next() } alert ('iterator1 和 iterator2 相等') }
外部迭代器虽然调用方式相对复杂,但它的适用面更广,也能满足更多变的需求。内部迭代 器和外部迭代器在实际生产中没有优劣之分,究竟使用哪个要根据需求场景而定。