迭代器和可迭代协议

525 阅读2分钟

迭代

类似于遍历

遍历:有多个数据组成的集合数据结构(map、set、array等其它类数组),需要从该结构中一次取出数据进行某种处理

迭代:按照某种逻辑,依次取出下一个数据进行处理

注意:能遍历一定可以进行迭代,可迭代的数据不一定能进行遍历

迭代器

JS语言规定,如果一个对象具有next方法,并且next方法满足一定的约束,则该对象就是一个迭代器(iterator)

  • next方法约束 该方法必须返回一个对象,该对象至少有两个属性:

value:any类型,下一个数据的值,如果 done为true,通常会将 value设置为 undefined

done:bool类型,是否以及迭代完成

var iterator = {
         toal: 3,// 可迭代次数
         i:0,// 当前迭代的次数
         next () {
             var obj =  {
                 value: this.i > 3 ? undefined: this.i,
                 done: this.i ++ > 3
             }
             return obj;
         }
    }

迭代器可以使用next方法,可以依次取出数据,并根据 done属性判断还有没有数据。

迭代器创建函数

它是指一个函数,调用该函数后,返回一个迭代器,则该函数称之为迭代器创建函数,可简称 迭代器创建函数。

  • 创建一个可迭代数组:
function createItrator(arr) {
    var i = 0;
    return {
        next() {
            value: arr[i++],
            done: i > arr.length;
        }
    }
}

可迭代协议

ES6出现了for-of循环,该循环就是用于迭代某个对象的,因此,for-of循环要求对象是可迭代的(对象必须满足可迭代协议)

可迭代协议:是用于约束一个对象的,如果一个对象满足下面规范,则该对象满足可迭代协议,则该对象是可以被迭代的。

可迭代协议约束如下:

1、对象必须要有一个知名符号属性(Symbol.iterator) 2、该属性必须是一个无参迭代器创建函数

var obj = {
      [Symbol.iterator]:function () {
          var i = 0;
          var total = 3;
          return {
              next() {
                  value: i++ > 3 ? undefined : i,
                  done: i > 3 ? true: false
              }
          }
      }
    }

for-of 循环的原理

调用对象的 [Symbol.iterator] 方法,得到一个迭代器。不断调用next方法只要返回的 done为false,则返回的value传递给变量,然后进入循环体执行。

模拟 for-of循环
var iterator = obj[Symbol.iterator]();
var result = iterator.next();
while(!result.done) {
    var item = result.value;
    console.log(item)
    result = iterator.next();
}

for(let item of obj) {
    console.log(item)
}