迭代器模式

108 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情

导言

MartinFlower曾经还说过,要取消迭代器模式这种设计模式。为什么呢?因为现在很多高级编程语言如Java、C#等本身已经将迭代器模式融入到了自己的语言中,所以觉得越来越没有必要。

其实不仅是Java或C#语言,JavaScript语言在ES6中也新增了Iterator接口机制,也是一种基于迭代器模式的设计。

迭代器模式,英文Iterator Design Pattern,也可以称为游标模式,Cursor Design Pattern。当遍历一个集合时,不管集合中的对象是否都是同类,如在JavaScript中集合可以是数组,也可以是对象,ES6还新增了Set和Map,只要集合中的对象都符合一定的统一条件,即可遍历,就是遍历过程中并不关心对象是什么,是什么类型,能提供个可遍历的接口或方法即可实现遍历。下面我们就通过ES6中的Iterator接口机制来看看...

Iterator接口

Iterator接口为各种数据结构提供统一的访问机制,任何数据结构只要部署了Iterator接口,就可以正常遍历。

作用

它的作用主要有两种:

  • 为各种数据接口提供统一的访问接口
  • 集合中成员能够按照某种次序顺序执行

在ES6中新增了for...of循环,Iterator接口主要就是为其服务的。

遍历过程

  • 创建一个指针对象,指向集合的初始位置
  • 执行next方法,指向第一个成员对象
  • 再执行next方法,执行第二个成员对象
  • 不断调用next方法,直到最后一个成员对象结束

怎么获取到当前成员的值和判断是否已经到了最后一个成员对象呢?其实每次执行next方法时,都会返回一个对象,对象中包含value和done值,value就是当前成员对象的值,done表示是否遍历已完成。

let it = customIterator(['a', 'b', 'c', 'd']);

it.next()   // { value: "a", done: false }
it.next()   // { value: "b", done: false }
it.next()   // { value: "c", done: false }
it.next()   // { value: "d", done: false }
it.next()   // { value: undefined, done: true }

function customIterator(array) {
  let curIndex = 0;
  return {
    next: function() {
      let ret = curIndex < array.length ?
        { value: array[curIndex++], done: false } : { value: undefined, done: true }
      return ret
    }
  }
}

代码中自定义了一个customIterator方法,就是为每个成员变量添加了统一的next方法来进行遍历,done属性返回true则表示成员都已经按序遍历完成。Iterator接口机制就是比较典型的迭代器设计模式。