迭代器模式

70 阅读2分钟

一、介绍

定义:

迭代器模式是一种行为设计模式, 让你能在不暴露集合底层表现形式 (列表、 栈和树等) 的情况下遍历集合中所有的元素。

个人理解:

JavaScript的已经内置了迭代器。Array,Map就是可迭代对象,内部实现了@@iterator,也就是 Symbol.iterator

主要解决:

不同的方式来遍历整个整合对象。

如何解决:

将集合的遍历行为抽取为单独的迭代器对象。

关键代码:

遍历算法的封装。

应用实例:

  1. Array
  2. Map

使用场景:

  1. 以减少程序中重复的遍历代码。
  2. 隐藏遍历的复杂代码。

优点:

  • 单一职责原则。 通过将体积庞大的遍历算法代码抽取为独立的类, 你可对客户端代码和集合进行整理。
  • 。 你可实现新型的集合和迭代器并将其传递给现有代码, 无需修改现有代码。
  • 你可以并行遍历同一集合, 因为每个迭代器对象都包含其自身的遍历状态。
  • 相似的, 你可以暂停遍历并在需要时继续。

缺点:

  • 如果你的程序只与简单的集合进行交互, 应用该模式可能会矫枉过正。

  • 对于某些特殊集合, 使用迭代器可能比直接遍历的效率低。

二、内部迭代器

定义:一个函数内部定义好遍历算法,它完全接口整个迭代过程,外部只需要一次初始化调用。

由于是内部定义,遍历算法无法修改,缺少灵活性。

var each = function (ary, callback) {
  for (var i = 0, l = ary.length; i < l; i++) {
    callback.call(ary[i], i, ary[i]); // 把下标和元素当作参数传给callback函数
  }
};

each([1, 2, 3], function (i, n) {
  alert([i, n]);
});

三、外部迭代器

定义:一个函数封装迭代的规则,接收一个对象,返回一个迭代器(对象,有next的方法,参考迭代器协议)。

var Iterator = function (obj) {
  var current = 0;
  var next = function () {
    current += 1;
  };

  var isDone = function () {
    return current >= obj.length;
  };

  var getCurrItem = function () {
    return obj[current];
  };

  return {
    next: next,
    isDone: isDone,
    getCurrItem: getCurrItem,
    length: obj.length
  }
};

var compare = function (iterator1, iterator2) {
  if (iterator1.length !== iterator2.length) {
    alert('iterator1和iterator2不相等');
  }
  while (!iterator1.isDone() && !iterator2.isDone()) {
    if (iterator1.getCurrItem() !== iterator2.getCurrItem()) {
      throw new Error('iterator1和iterator2不相等');
    }
    iterator1.next();
    iterator2.next();
  }

  alert('iterator1和iterator2相等');
}

compare(Iterator([1, 2, 3]), Iterator([1, 2, 4]))

四、拓展

迭代器模式

迭代器

JavaScript中,迭代器是一个对象,内部通过next方法实现了迭代器协议。next方法返回一个对象,{done:boolean,value:''}

{
  done:false,
  value:1
}

{
  done:true
}

迭代器和生成器 - JavaScript | MDN (mozilla.org)

迭代协议

迭代协议 - JavaScript | MDN (mozilla.org)

倒序迭代器

中止迭代器