什么是 JavaScript 迭代器?在哪里可以使用它们?

JavaScript 迭代器是在 ES6 中引入的,它们用于循环一系列值,通常是某种集合。根据定义,迭代器必须实现一个next()函数,该函数以{ value, done } 的形式返回对象,其中value是迭代序列中的下一个值,并且done是一个布尔值,确定序列是否已被消费完。

一个在实际项目中实际使用的非常简单的迭代器可能如下所示:

class LinkedList {
  constructor(data) {
    this.data = data;
  }

  firstItem() {
    return this.data.find(i => i.head);
  }

  findById(id) {
    return this.data.find(i => i.id === id);
  }

  [Symbol.iterator]() {
    let item = {next: this.firstItem().id};
    return {
      next: () => {
        item = this.findById(item.next);
        if(item) {
          return {value: item.value, done: false};
        }
        return {value: undefined, done: true};
      }
    };
  }
}

const myList = new LinkedList([
  {id: 'a10', value: 'First', next: 'a13', head: true },
  {id: 'a11', value: 'Last', next: null, head: false },
  {id: 'a12', value: 'Third', next: 'a11', head: false },
  {id: 'a13', value: 'Second', next: 'a12', head: false }
]);

for(let item of myList) {
  console.log(item);    // 'First', 'Second', 'Third', 'Last'
}

在上面的示例中,我们实现了一个LinkedList数据结构,该数据结构在内部使用一个data数组,其中每项都有一个value,以及一些用于确定序列位置的特定实现的属性。从此类构造的对象默认情况下是不可迭代的,因此我们通过使用进行定义Symbol.iterator并设置了迭代器,以使返回的序列基于该类的内部实现按顺序排列,而返回的项仅返回它们的value

值得一提的是,迭代器只是函数,意味着它们可以像其他任何函数一样被调用(例如,将迭代委派给现有的迭代器),同时也不限于Symbol.iterator名称,从而使我们可以为同一对象定义多个迭代器。这是这些概念的示例:

class SpecialList {
  constructor(data) {
    this.data = data;
  }

  [Symbol.iterator]() {
    return this.data[Symbol.iterator]();
  }

  values() {
    return this.data
      .filter(i => i.complete)
      .map(i => i.value)
      [Symbol.iterator]();
  }
}

const myList = new SpecialList([
  {complete: true, value: 'Lorem ipsum'},
  {complete: true, value: 'dolor sit amet'},
  {complete: false},
  {complete: true, value: 'adipiscing elit'}
]);

for(let item of myList) {
  console.log(item);  // The exact data passed to the SpecialList constructor above
}

for(let item of myList.values()) {
  console.log(item);  // 'Lorem ipsum', 'dolor sit amet', 'adipiscing elit'
}

在此示例中,我们使用data对象的本机数组迭代器使其SpecialList可迭代,并返回data数组的确切值。同时,我们还定义了一个values方法,该方法本身是迭代器,在data数组上使用Array.prototype.filter()Array.prototype.map(),然后最终返回Symbol.iterator结果,仅允许对序列中的非空对象进行迭代,并返回每个对象的value

原文链接:https://www.30secondsofcode.org/blog/s/javascript-iterators

你可能感兴趣的:(什么是 JavaScript 迭代器?在哪里可以使用它们?)