ES6中的迭代器

105 阅读2分钟

什么是迭代?

从一个数据集合中按照一定的顺序,不断取数据的过程

迭代和遍历的区别

  • 迭代:强调的是依次取数据,并不保证取多少,也不保证把所有的数据取完
  • 遍历:强调的是将一个已知集合所有数据依次全部取出

在JS中可迭代协议

要成为可迭代对象,该对象必须实现   @@iterator 方法,这意味着对象(或者它原型链上的某个对象)必须有一个键为 @@iterator 的属性,可通过常量 Symbol.iterator 访问该属性:

迭代器协议

迭代器协议定义了产生一系列值(无论是有限个还是无限个)的标准方式,当值为有限个时,所有的值都被迭代完毕后,则会返回一个默认返回值。

迭代器:对迭代过程的封装通常是一个对象

  • 拥有一个next()
  • next()返回一个{value:any,done:boolen}格式的对象
  • value:迭代器返回的任何 JavaScript 值。done 为 true 时可省略。
  • done:标志着迭代过程是否已经结束
    // 这就是一个迭代器
    const obj = {
        next:(){
            return {
                value:1
                done:false
            }
        }
    }

迭代器的例子

    const arr = [1,2,3,4,5,6]
    const iterator = {
        index:0,
        next:(){
            const result =  {
                value:arr[this.index],
                done:this.index >= arr.length
            }
            this.index++;
            return result
        }
    }

image.png

迭代器创建函数

在上边的例子中实现了对arr的迭代,但是这个迭代器不具有通用性,所以可以在进行一下优化

   const arr = [1, 2, 3, 4, 5, 6];
const arr2 = ["d", "g", "de", "dge"];
const iteratorGenerator = function (data) {
  return {
    index: 0,
    next() {
      const result = {
        value: data[this.index],
        done: this.index >= data.length,
      };
      this.index++;
      return result;
    },
  };
};

const arrIt = iteratorGenerator(arr);
const arr2It = iteratorGenerator(arr2);

这样我们就实现了一个通用的迭代器

image.png

如何通过迭代器拿出所有的数据?

// 接上边的例子
let resultData = arrIt.next();

while (!resultData.done) {
  console.log(resultData);
  resultData = arrIt.next();
}

image.png

for...of..

for...of语句可迭代对象(包括 ArrayMapSetStringTypedArrayarguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句

如何使一个迭代器也可以迭代(可迭代对象)

生成器对象是一个例子


      // 这就是一个迭代器
    const obj = {
        next:(){
            return {
                value:1
                done:false
            }
        }
    }
    
    // 稍微改动下
    
    const obj = {
        next:(){
            return {
                value:1
                done:false
            }
        }
        [Symbol.iterator]{
            return this
        }
    }
    

最后练习下如何使一个斐波那契数列可迭代

const arr = [1, 1, 2, 3, 5, 8, 13];

const it = {
  prev1: 1,
  prev2: 1,
  currentIndex: 1,
  next() {
    let value = this.currentIndex++ <= 2 ? 1 : this.prev1 + this.prev2;
    const result = {
      value: value,
      done: false,
    };
    this.prev2 = this.prev1;
    this.prev1 = value;
    return result;
  },
};

image.png

如果有错误的地方希望路过的大佬们可以指正