《js 设计模式与开发实践》读书笔记 7


  迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。迭代器模式可以把迭代的过程从业务逻辑中分离出来,在使用迭代器模式之后,即使不关心对象的内部构造,也可以按顺序访问其中的每个元素。

  我们来实现一个 each 函数,each 函数接受两个参数,第一个为被循环的数组,第二个为循环中每一步后将被触发的回调函数。

var each = function (ary, callback) {
  for (let i = 0; i < ary.length; i++) {
    const element = ary[i]
    callback(element, i)
  }
}

each([1, 2, 3], function (i, n) {
  console.log(i, n)
})

  迭代器可以分为内部迭代器和外部迭代器,它们又各自的使用场景。上面的 each 函数是内部迭代器,each 函数的内部已经定义好了迭代规则,它完全接手整个迭代过程,外部只需要一次初始调用。内部迭代器在调用的时候非常方便,外界不用关心迭代器内部的实现,跟迭代器的交互仅仅是一次初始调用,但也这也是内部迭代器的缺点。因为内部迭代器的迭代规则已经被提前规定,就无法满足一些别的请求。

  假如现在有个需求,需要判断 2 个数组里元素的值是否完全相等,如果不改写 each 函数本身的代码,我们只能在回调函数修改了。

var each = function (ary, callback) {
  for (let i = 0; i < ary.length; i++) {
    const element = ary[i]
    callback(element, i)
  }
}

var compare = function (ary1, ary2) {
  if (ary1.length != ary2.length) {
    console.log('ary不相等。')
    return
  }
  each(ary1, function (i, n) {
    if (i != ary2[n]) {
      console.log('ary不等')
      return
    }
  })
  console.log('ary相等')
}

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

   这个函数不好看,但是目前的需求暂时可以完成。外部迭代器必须显式请求迭代下一个元素。

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

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

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

  return {
    next: next,
    isDone: isDone,
    getCurrentItem: getCurrentItem,
    length: obj.length
  }
}

  外部迭代器调用方式相对复杂,但是更容易满足多变的需求。迭代器模式不仅可以迭代数组,还可以迭代一些类数组的对象。只要迭代的聚合对象拥有 length 属性而且可以用下标访问,那它就可以迭代。

  上面的 foreach 函数我们想要便利到对应方法停止就需要把条件传进去,然后 break 了,这也是为什么 foreach 函数会直到数组玄幻完毕。而要用 every 函数了。every 写一个。

var every = function (ary, callback) {
  for (let i = 0; i < ary.length; i++) {
    const element = ary[i]
    if (!callback(element, i)) {
      break
    }
  }
}

var compare = function (ary1, ary2) {
  if (ary1.length != ary2.length) {
    console.log('ary不相等。')
    return false
  }
  every(ary1, function (i, n) {
    if (i != ary2[n]) {
      console.log('ary不等')
      return false
    }
    return true
  })
  console.log('ary相等')
}

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

   迭代器是一种相对简单的模式,简单到很多时候我们都不认为它是一种设计模式。

posted @ 2022-09-16 11:10  艾路  阅读(15)  评论(0编辑  收藏  举报