迭代器和生成器

  学习的时候都学到过for循环,while循环等等,为什么会需要循环操作呢?因为有些时候我们希望计算机为我们重复的执行同样的操作,比如有一个“数组”,里面存储了10个数字,那么则会对这个数组进行循环操作,然后挨个输出。

  我们可以很容易的用循环来遍历一个数组,因为数组在内存中的存储是连续的,可以通过数组的“下标”(就是相对于数组第一个元素的位置)来进行访问数组中的元素。那么如果进行遍历一个没有在内存中连续存储的“数据结构”呢,比如”对象“,那么传统的for循环,while循环就无法发挥他们的作用了,这个时候我们就需要引入“迭代器”。

 

迭代器

  迭代是一个重复的过程,迭代器就是每次重复都是基于上次结果而继续的。迭代器用于给数据结构提供统一的访问遍历的机制,可以把迭代器看成比普通循环更高级别的工具,普通循环能搞定的迭代器也能搞定,普通循环搞不定的迭代器还能搞定。ES6之前的迭代器比较麻烦,而现在引入了生成器对象,让迭代器更加容易使用。

生成器

  用关键字 yield 来返回值,这种函数叫生成器函数。生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个(自定义)迭代器。 在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值,并在下一次执行 next() 方法时从当前位置继续运行。
 

  yield后就是要迭代的对象,注:方法名前须加上*号

 function *cit(){
    yield 1;
    yield 2;
    yield 3;
}
let it=cit();

console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());

   使用 .next() 进行遍历,返回一个对象,value表示值,如果没有会返回 undefined;done表示下面是否还有可遍历内容,有返回false,没有返回true。

 如果想以匿名函数的方法,把 * 放在 () 前即可:

let cit=function *(){
    yield 1;
    yield 2;
    yield 3;
}

 

 

 

结合循环语句,将数组作为参数,将数组中每一个值都添加到迭代中:

function *cit(items){
    for(let i=0;i<items.length;i++){
        yield items[i]
    }
}
let it=cit([1,2,3]);
console.log(it.next().value); //1
console.log(it.next().value); //2
console.log(it.next().value); //3
console.log(it.next().value); //undefined

 

默认迭代接口

  很多数据结构类型拥有默认迭代接口,比如:Array、Set、Map等。对于原生就支持迭代器的数据结构,是不用自己编写生成器迭代器,使用(最简单的迭代方式)for...of 迭代语句去遍历即可。

  以 Array 数组类型为例,它提供了有关三个方法:keys()values()entries()

let items=["a","b","c"];
for(let i of items){
    console.log(i);
}
//Array Iterator迭代器 {}
console.log(items.keys());
console.log(items.values());
console.log(items.entries());

        

    keys() :下标

for(let i of items.keys()){
    console.log(i); //0  1  2
}

    values() :元素

for(let i of items.values()){
    console.log(i); //a  b  c
}

    entries() :key+val

for(let i of items.entries()){
    console.log(i); //[0, 'a']  [1, 'b']  [2, 'c']
}

依然支持 .next() 语法

let items=["a","b","c"];
let vals=items.values();
console.log(vals.next());
console.log(vals.next());
console.log(vals.next());
console.log(vals.next());

 

 

posted @ 2021-11-29 21:30  十七日尾  阅读(53)  评论(0)    收藏  举报