Javascript chapter12 迭代器和发生器
1.数组,TypedArray strings Set Map 对象时可迭代的。
let sum=0;
for(let i of [1,2,3]){
sum+=i;
}
2 使用...操作符
let chars=[..."abcd"];//chars=["a","b","c","d"];
let data =[1,2,3,4,5];
Math.max(...data);//5
3.可以desctrcuring assignment
let purpleHaze=Uint8Array.of(255,0,255,128);
let [r,g,b,a]=purpleHaze;//a=128
Map迭代会返回键值对
let m=new Map([["one",1],["two",2]]);
for (let[k,v] of m)console.log(k,v);//'one 1' 'two 2'
如果你只想用键或者值使用keys() values()方法
[...m] //[["one",1],["two",2]];
[...m.entries()//[["one",1],["two",2]] same
[...m.keys()]//["one","two"]
[...m.values()]//[1,2]
4.什么是迭代器?
可迭代对象是对象实现了next()方法。返回了迭代结果对象。迭代结果对象是命名了value done属性的对象。
迭代可迭代对象,首先调用迭代方法获得迭代对象,接着调用next()方法,直到可迭代对象返回done的值设为true
工作类似于下例
let iterable[99];
let iterator = iterable[Symbol.interator]();
for(let result=iterator.next();!result.done;result=iterator.next()){
console.log(result.value);//result.value=99
}
12.2实现Iterable 对象
要使一个对象是可迭代的,必须实现Symbol.iterator方法,这个方法必须返回实现了next()方法的可迭代对象。
next()方法必须返回,迭代结果对象(iteration result object)拥有value属性和布尔值属性done。
下例:
class Range{
constructor(from,to){
this.from=from;
this.to=to;
}
//判断x是否在范围内
has(x){return typeof x==="number"&&this.from<=x&&x<=this.to;}
toString(){return `{x|${this.from}<=x<=${this.to}`;};
//Make a Range iterable by returning an iterator object.
//Note that the name of this method is a special symbol,not a string;
[Symbol.iterator]{
//Each iterator instance must iterate the range independently of others.So we need a state variable to track our location
//in the iteration .We start at the first integer>=from
let next=Math.ceil(this.from);//This is the next value we return
let last =this.to;//We won't return anything >this
return{ //This is the iterator object
//This next() method is what makes this an iterator object.
next(){
return (next<=last)?{value:next++}:{done:true};
},
[Symbol.iterator(){return this;}
};
}
}
调用
for(let x of new Range(1,10))console.log(x);
[...new Range(-2,2)]//[-2,-1,0,1,2]
迭代器有可能在迭代完成前终止,包括break ,实现return()方法用于关闭文件,清理资源等活动。return()要返回一个对象,一般是迭代结果对象。
12.3发生器Generators
发生器function*.调用时不处理函数体,返回一个发生器对象。这个对象是迭代器。
调用next()方法,发生器函数从函数体最前端开始运行直到遇到yield语句。
例
//A generator function that yeilds the set of one digit primes
//Invoking this function does not run the code but just returns a generatorobject.calling the next() method of that generator runs
//the code until a yield statement providesthe return value for the next method;
function * oneDigitPrimes(){
yield 2;
yield 3;
yield 5;
yield 7;
}
let primes=oneDigitPrimes();
primes.next().value;//2
primes.next().value;//3
primes.next().value;//5
primes.next().value;//7
primes.next().done;//true
[...oneDigiPrimes()] //[2,3,5,7]
let sum=0;
for(let prime of oneDigitPrimes())sum+=prime;
sum//17
另一种定义方法
const seq=function *(from,to){
for(let i=from;i<=to;i++)yield i;
};
[...seq(3,5)]//[3,4,5]
在对象或者类中可以使用*缩写function *
let o={
x:1,y:2,z:3,
*g(){
for(let key of Object.keys(this){
yield key;
}
}
};
[...o.g()]//["x","y","z","g"]
12.3.1 发生器实例
无限迭代器
function * fibonacciSequence(){
let x=0,y=1;
for(;;){
yield y;
[x,y]=[y,x+y];
}
}
使用...调用会死循环。则
function * take(n,iterable){
let it =iterable[Symbol.iterator]();
while(n-->0){
let next=it.next();
if(next.done)return;
else yield next.value;
}
}
[...take(5,fibonacciSequence)]//[1,1,2,3,5]
12.3.2 yield* 和递归发生器
yield*关键字用于返回迭代器的结果
function* sequence(...iterables){
for(let iterable of iterables){
yield* iterable;
}
}
[...sequence("abc",oneDigitPrimes())]//["a","b","c",2,3,5,7];
注意yield 和yield*只用在Generator发生器中。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律