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发生器中。

posted @   zhongta  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示