当前位置: 首页 > Web前端 > JavaScript

[js]迭代器和生成器

时间:2023-03-27 10:38:22 JavaScript

迭代器(Iterator)有时也被称为遍历器——迭代器对象的作用是为各种数据结构提供统一的访问接口,使数据结构的成员按照一定的顺序排列。for...of循环的统一迭代方法1.Iterable(可迭代)iterable:具有Symbol.iterator属性的数据结构是可迭代的Symbol.iterator:值为迭代器生成函数。原始可迭代数据结构:ArrayMapSetStringTypedArrayargumentsNodeList这些数据结构可以使用for...of来遍历//以数组为例,判断是否有Symbol.iterator属性constarr=[1,2,3,4]Symbol.iteratorinarr//true//for...of遍历数组for(constiofarr){console.log(i)//1234}2.迭代器生成函数(Symbol.iterator)returnsaniteratorobjectconstarr=[1,2,3,4]console.log(arr[Symbol.iterator]())迭代器中有一个next函数next()会返回一个成员对象,有两个属性value和done,value表示当前成员的值,done表示遍历是否终止for...of每次都会调用next函数,取value2.1next()方法constarr=[1,2,3,4]letiter=arr[Symbol.iterator]()//返回一个遍历器对象console.log(iter.next());//{value:1,done:false}console.log(iter.next());//{值:2,完成:false}console.log(iter.next());//{value:3,done:false}console.log(iter.next());//{value:4,done:false}console.log(iter.next());//{value:undefined,done:true}遍历器对象可以看作是一个指针,每次调用上面的next方法都会移动指针2.2实现迭代器生成函数数组//实现函数makeIterator(arr){varnextIndex=0;return{next(){returnnextIndex5+1第二次返回resulty由第一个yield计算得到,其值为第二个next()中的参数2*12/3=8z值由第二个yield计算得到,其值为第三个next()中的参数5+24+13=42function*generator(){letval1=yield1console.log(""val1);letval2=yield2console.log(val2);}letiter=generator()iter.next("one")iter.next("two")//第一个的值yield:twoiter.next("three")//第二个yield的值:three2.yield语句普通的yield语句可以中断执行,return转换yield*后面可以跟一个迭代器对象,相当于在生成器函数中调用另一个生成器*generator1(){yield1yield2}function*generator2(){yield'a'yield*generator1()yield'b'return'c'}letgene2=generator2()for(constiofgene2){console.log(i)//'a'12'b'}在一个yield*中执行另一个生成器,相当于把它的语句插入到生成器中。return返回的done为真,for...of在遍历时不会返回其值如果yield之后执行了一个生成器,next返回的值是一个迭代器对象function*generator1(){yield1yield2}function*generator2(){yield'a'yieldgenerator1()}letgene2=generator2()console.log(gene2.next());console.log(gene2.next());3.Generator.prototype.throw()3.1函数外部抛出错误,内部捕获function*generator(){try{yield1yield2yield3}catch(e){console.log("Internalcapture:"+e);}}letgene=generator()try{console.log(gene.next());gene.throw("第一个错误");console.log(gene.next());gene.throw("第二个错误");console.log(gene.next());gene.throw("第三个错误");console.log(gene.next());}catch(e){console.log("外部捕获:"+e);}第一次调用throw会在内部catch中捕获,try中的语句为不再执行出错后,调用next是一个终止状态的对象,表示生成器已经终止。由于generator被终止,第二个错误会被外部捕获,generator会彻底终止,调用上面的方法将不再生效。3.2返回值throw返回nextnextfunction*generator(){try{console.log(1);产生“in11”console.log(2);yield"in12"}catch(e){console.log("内部捕获1");}console.log(3);yield"out1"try{console.log(4);产量“in21”console.log(5);yield"in22"}catch(e){console.log("InternalCapture2");}控制台日志(6);yield"out2"yield"out3"}letgene=generator()try{console.log(gene.next());//1{value:'in11',done:false}console.log(gene.throw());//内部捕获13{value:'out1',done:false}console.log(gene.next()));//4{value:'in21',done:false}console.log(gene.throw());//内部捕获26{value:'out2',done:false}console.log(gene.throw());//内部捕获.next());//7{value:'out3',done:false}console.log(gene.throw());//外部捕获console.log(gene.next());}catch(e){console.log("externalcapture");}上面代码中有多个trycatch的第一个next会进入到firsttry中firstthrow的调用环境。如果有catch,则跳出try,执行到下一个yield。如果下一个yield有一个catch,throw可以继续。如果没有catch,会在外部捕获并生成捕获到错误后generator终止throw,然后返回nextnext的返回值4.Generator.prototype.return()返回给定的值,并终止generator函数*generator(){yield1yield2yield3}letgene=generator()gene.next()//{value:1,done:false}gene.return("foo")//{value:"foo",done:false}gene.next()//{value:undefined,done:false}如果在try..finally中,return将在finally之后运行function*generator()。{try{yield1yield2}finally{yield3yield4}yield5}letgene=generator()console.log(gene.next());//{value:1,done:false}console.log(gene.return(6));//{value:3,done:false}console.log(gene.next());//{value:4,done:false}console.log(gene.next());//{值:6,完成:true}console.log(gene.next());//{value:undefined,done:true}第一个next进入try,如果直接return则直接结束执行try中的return,进入final在ly中,执行到第一个yield,返回status,在finally的末尾加上return。在finally中执行return会直接结束5.部署一个Iterator接口对象function*iterEntries(obj){letkeys=Object.keys(obj)for(leti=0;i