JavaScript迭代协议
阅读原文时间:2023年08月11日阅读:4

JavaScript迭代协议解读

迭代协议分为可迭代协议迭代器协议

协议指约定俗成的一系列规则。

可迭代协议规定了怎么样算是一个可迭代对象:可迭代对象或其原型链上必须有一个键为[Symbol.iterator]的属性。

一些内置类型如Array和Map均是可迭代对象,而Object不是。

let a = new Map();
let b = Object();
console.log(Symbol.iterator in a);//true
console.log(Symbol.iterator in b);//false

Symbol.iterator是一个无参函数,查看可迭代对象的原型链([[Prototype]])可知,它指向了entris(),调用它将返回一个符合迭代器协议迭代器对象

console.log(a[Symbol.iterator]);//[Function:entries]

完成迭代

a.set(1,1).set(2,2).set(3,3);
console.log(a.entries());//[Map Entries] { [ 1, 1 ], [ 2, 2 ], [ 3, 3 ] }
console.log(...a);//[ 1, 1 ] [ 2, 2 ] [ 3, 3 ]

迭代器是按需创建的一次性接口对象,每个迭代器都会关联一个可迭代对象。

迭代器协议规定:实现了Iterabor接口的同时定义了一个next()方法的对象为一个迭代器。

迭代器具有三个方法:next()、return()和throw()。后两个是可选的。

  • next():无参数或者接受一个参数,并返回一个符合 IteraborResult 接口的对象。

    IteraborResult有两个属性:

    • done:为true时,迭代终结;为false时,迭代继续。
    • value:value作为返回值返回,done为true时忽略。
  • return(value):无参数或者接受一个参数,执行必要的清理工作(例如关闭数据库连接),并返回一个符合 IteraborResult 接口的对象,通常返回的value等于传进来的arguments.value,而done为true。

  • throw():无参数或者接受一个参数的函数,并返回符合 IteratorResult 接口的对象。

接下来,手动使用类实现一个迭代器:

class myIterator{
  constructor(limit){
    this.limit=limit;
  }
  [Symbol.iterator](){
    let count=1,limit=this.limit;
    return{
      next(){
        if(count<=limit){
          return {done:false,value:count++};
        }
        else{
          return {done:true,value:undefined};
        }
      }
    }
  }
}
let my_iterator=new myIterator(3);
for(let i of my_iterator) console.log(i);
/**
 * 1
 * 2
 * 3
 */

或者用生成器实现迭代器:

const myIterator = {
  *[Symbol.iterator]() {
    yield 1;
    yield 2;
    yield 3;
  },
};
console.log([...myIterator]);

function * idMaker(){
  let id = 0;
  while (true) {
    yield id++;
  }
}
const it = idMaker();
console.log(it.next().value);//0