第十章 设计模式 - 行为型 - 迭代器模式

发布时间 2023-03-28 15:48:15作者: caix-1987

迭代器模式的概念

1、迭代器模式号称“遍历专家”,它提供一种方法顺序访问一个聚合对象中的各个元素,且不暴露该对象的内部表示。

2、迭代器又分 2 类

  1、内部迭代器( jquery.each / for...of )
  
  2、外部迭代器( es6 yield )

3、在 es6 之前,直接通过 forEach 遍历 DOM NodeList 和函数的 arguments 对象,都会直接报错,其原因都是因为他们都是类数组对象。对此 jquery 很好的兼容了这一点。

4、在 es6 中,它约定只要数据类型具备 Symbol.iterator 属性,就可以被 for...of 循环和迭代器的 next 方法遍历。

迭代器模式的例子

1、Array.prototype.forEach

2、jQuery中的 $.each()

3、ES6 Iterator

迭代器模式的代码示例

class Iterator {
    constructor(conatiner) {
        this.list = conatiner.list
        this.index = 0
    }
    next() {
        if (this.hasNext()) {
            return this.list[this.index++]
        }
        return null
    }
    hasNext() {
        if (this.index >= this.list.length) {
            return false
        }
        return true
    }
}

class Container {
    constructor(list) {
        this.list = list
    }
    getIterator() {
        return new Iterator(this)
    }
}

// 测试代码
let container = new Container([1, 2, 3, 4, 5])
let iterator = container.getIterator()
while(iterator.hasNext()) {
  console.log(iterator.next())
}
(function (a, b, c) {
	const arg = arguments;
  const iterator = arg[Symbol.iterator]();
  
  console.log(iterator.next()); // {value: 1, done: false}
  console.log(iterator.next()); // {value: 2, done: false}
  console.log(iterator.next()); // {value: 3, done: false}
  console.log(iterator.next()); // {value: undefined, done: true}
})(1, 2, 3)
通过 es6 内置生成器 Generator 实现迭代器并没什么难度,这里重点通 es5 实现迭代器

function iteratorGenerator (list) {
  var index = 0;
  // len 记录传入集合的长度
  var len = list.length;
  return {
    // 自定义 next 方法
    next: funciton () {
      // 如果索引还没有超出集合长度,done 为 false
      var done = index >= len;
      // 如果 done 为 false,则可以继续取值
      var value = !done ? list[index++] : undefined;

      // 将当前值与遍历是否完毕(done)返回
      return {
        done: done,
        value: value
      };
    }
  }
}

var iterator = iteratorGenerator([1, 2, 3]);
console.log(iterator.next()); // {value: 1, done: false}
console.log(iterator.next()); // {value: 2, done: false}
console.log(iterator.next()); // {value: 3, done: false}
console.log(iterator.next()); // {value: undefined, done: true}

迭代器模式的总结

小结

  实现统一遍历接口,符合单一功能和开放封闭原则。

使用场景

  有遍历的地方就有迭代器。
  
  对于集合内部结果常常变化各异,不想暴露其内部结构的话,但又想让客户代码透明的访问其中的元素,可以使用迭代器模式
  
特点

  1、访问一个聚合对象的内容而无需暴露它的内部表示。
  
  2、为遍历不同的集合结构提供一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作