JavaScript-迭代器

50 阅读2分钟

什么是迭代器

迭代器,是帮助我们对某个数据结构进行遍历的对象。

在JavaScript中,迭代器也是一个对象,这个对象需要符合迭代器协议:在JavaScript中这个标准就是这个对象需要有一个特定的next方法

next方法

要求:

  • 要求一:一个无参数或一个参数的函数
  • 要求二:next方法返回值需要是一个对象,这个对象中要有两个属性done、value
    • done:用于判断迭代器是否可以产生序列中的下一个值。false为可以,true为不可以
    • value: 返回的值,当done为true时,可以省略或者为undefined
const names = ['name1', 'name2', 'name3', 'name4']

// 创建一个数组的迭代器
function createArrIterator(arr) {
  let index = 0
  // 迭代器是一个具体的对象,并且有一个next方法
  // next方法需要返回一个对象 { done: 不可迭代时为true, value: 迭代时得到的值,done为true时可以为空,也可以为undefined }
  return {
    next: function() {
      if (index < arr.length) {
        return { done: false, value: arr[index++] }
      }else {
        return { done: true, value: undefined }
      }
    }
  }
}

const namesIterator = createArrIterator(names)
console.log(namesIterator.next());
console.log(namesIterator.next());
console.log(namesIterator.next());
console.log(namesIterator.next());
console.log(namesIterator.next());

可迭代对象

可迭代对象的要求:

    1. 这个对象必须得实现一个特定的函数: [Symbol.iterator]
    1. 这个[Symbol.iterator]函数需要返回一个迭代器,这个迭代器用于迭代当前对象
const infos = {
  names: ["nam1", "name2", "name3", "name4"],
  [Symbol.iterator]: function () {
    let index = 0
    // 这个对象为迭代器
    const iterator = { 
      next: () => {
        if (index < this.names.length) {
          return { done: false, value: this.names[index++] }
        } else {
          return { done: true, value: undefined }
        }
      },
    };
    return iterator
  },
};


// 可迭代对象可以通过for...of进行迭代
for (const name of infos) {
  console.log("name", name)
}

可以通过实现迭代器中的return方法来监听循环的中断

const infos = {
  names: ["nam1", "name2", "name3", "name4"],
  [Symbol.iterator]: function () {
    let index = 0
    // 这个对象为迭代器
    const iterator = { 
      next: () => {
        if (index < this.names.length) {
          return { done: false, value: this.names[index++] }
        } else {
          return { done: true, value: undefined }
        }
      },
      return: () => {
        console.log('监听到循环中断')
        return { done: true, value: undefined }
      }
    };
    return iterator
  },
};


for (const name of infos) {
  if (name == 'name2') {
    // 中断循环
    break
  }
}