开来围观Iterator啦

332 阅读2分钟

这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战

Iterator(遍历器)

概念

  • Iterator(遍历器):是一种用来统一的接口机制,用于处理所有不同的数据结构。
  • Iterator(遍历器):是一种接口,为各种不同的数据结构提供统一的访问机制
  • 任何数据结构只要部署 Iterator接口,就可以完成遍历操作。
  • Iterator的作用:
    1. 为各种数据结构提供一个统一的简便的访问接口。
    2. 使数据结构的成员能够按照某种次序排列。
    3. 为es6创造了一种新的遍历命令 for... of 循环,Iterator接口主要为for...of消费

Iterator遍历过程

  1. 创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。
  2. 第一次调用指针对象的next方法,将指针指向数据结构的第一个成员。
  3. 第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。
  4. 不断调用指针对象的next方法,直到它指向数据结构的结束位置。
  • 注意: 每一次调用next方法,都会返回数据结构的当前成员的信息。即返回一个包含value和done两个属性的对象。value是当前成员的值,done是一个布尔值,表示遍历是否结束。

一个遍历器函数:

function Iterator(array) {
    let nextIndex = 0;
    return {
        next: function() {
            return nextIndex < array.length ? 
            {value: array[nextIndex]} : 
            {done: true}
        }
    }
}

typeScript写法

interface Iterable {
  [Symbol.iterator]() : Iterator,
}

interface Iterator {
  next(value?: any) : IterationResult,
}

interface IterationResult {
  value: any,
  done: boolean,
}

默认的Iterator接口

  • 当使用for...of循环遍历某种数据结构时,该循环会自动去寻找Iterator接口。
  • 一种数据结构只要部署了 Iterator 接口,我们就称这种数据结构是“可遍历的”(iterable)。
  • ES6 规定,默认的 Iterator 接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”(iterable)
  • Symbol.iterator属性本身是一个函数,就是当前数据结构默认的遍历器生成函数。执行这个函数,就会返回一个遍历器。至于属性名Symbol.iterator,它是一个表达式,返回Symbol对象的iterator属性,这是一个预定义好的、类型为 Symbol 的特殊值,所以要放在方括号内
const obj = {
  [Symbol.iterator] : function () {
    return {
      next: function () {
        return {
          value: 1,
          done: true
        };
      }
    };
  }
};

原生具备Iterator接口的数据结构:

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • 函数的arguments对象
  • NodeList对象

从上面我们可以看出,对象(Object)不具备默认的Iterator接口,所以不可以使用for...of遍历。

调用Iterator接口的场合

  • 解构赋值
  • 扩展运算符
  • yield*
  • 其他场合:
    • for...of
    • Array.from()
    • Map(),Set(),WeakMap(),WeakSet()
    • Promise.all()
    • Promise.race()

方法

遍历器对象的方法:

  • next(): 必须部署,
  • return(): 可选的,
  • throw(): 可选的