es6 迭代器和生成器

本文详细介绍了ES6中的迭代器和生成器。迭代器是对数据按顺序取出的封装,拥有next方法和数据状态判断。自定义迭代器示例包括数组和斐波那契数列。生成器函数通过yield实现函数的分段执行,可以通过next方法控制执行流程。此外,还展示了如何在生成器中调用其他生成器以及在实际应用中生成数组的生成器。
摘要由CSDN通过智能技术生成

迭代器

1.什么是迭代?
将数据按照一定的顺序依次取出的过程叫迭代
迭代能将数据依次取出但是不能保证数据全部取出,也不能确定取出的个数
2.什么是迭代器?
对迭代过程的封装对象。
迭代器拥拥有获取下一个数据的功能 在返回的数据中存在有数据状态,判断是否可以继续向下继续迭代。
3.js中规定的迭代器
js中规定 一个对象中 含有next方法 并且这个next方法返回一个对象 那么我们就认为这个对象为迭代器

迭代器(对象)

        var obj  = {
            next() {
                // 用于获取下一个值
              return { 
                //   返回的数据 
                  value : "测试",
                //   判断是否继续
                  done : false
              }  
            }
        }

自定义的迭代器(数组)

接下来我们来写一个自定义的迭代器(数组)

        let arr = [1,2,3,4];
        // isiterator(迭代器)
        const isiterator = {
            // 声明变量让它从0开始迭代
            num : 0,
            next() {

               var result =  {
                    value : arr[this.num],
                    // 设置迭代状态 (是否继续)
                    done : this.num >= arr.length 
                }
          this.num++;
                return result;
            }
        }

        console.log(isiterator);
        // 调用next每次取出对应的状态和值
        console.log(isiterator.next());

每调用一次就会取出一个值,在这里return运用了闭包的原理
试着封装一下自定义数组的迭代器

function isiterator(arr) {
            // 声明一个变量让它从0开始迭代
            let num = 0;
            return {
                next() {

                    var result = {
                        value: arr[num],
                        // 设置迭代状态 (判断是否继续)
                        done: num >= arr.length
                    }
                    num++;
                    return result;
                }
            }

        }

自定义斐波拉契

接着我们来封装个经典的斐波拉契
斐波拉契主要数据排列为:1,1,2,3,5…
即除了第一个和第二个为1以外,后面的为前两个之和

function createFeiboIter() {
            // 定义数组初始值
            let a = 1;
            let b = 1;

            // 记录当前位置
            let num = 1;
            return {
                next() {
                    let value;
                    if (num <= 2) {
                        value = 1;
                    } else {
                        value = a + b;
                    }
                    var res = {
                        value,
                        da: false // 因为斐波拉契没有极限值所以返回一直为Flase即可以持续继续
                    }
                    // 初始值重新赋予
                    a = b;
                    b = res.value;
                    num++;
                    return res;

                }
            }
        }        
        var iterator = createFeiboIter();
        console.log(iterator.next().value); // 1
        console.log(iterator.next().value); // 1
        console.log(iterator.next().value); // 2
        console.log(iterator.next().value); // 3
        console.log(iterator.next().value);//5

结果如图:
在这里插入图片描述

数组的迭代器
// 在ES6里面 对象具有知名符号Symbol.iterator这个属性,这个对象就可以进行迭代

let arr = arr[Symbol.iterator]();

对象设置迭代器

for of方法
数组可以直接用for of便利
普通和对象里面没有iterator接口 所以无法使用for-of进行遍历
类数组对象也可以进行遍历
对象设置迭代器

var obj = {
            a : 1, 
            b : 2,
            c : 3,
//让其可以使用for of方法
            [Symbol.iterator] () {
                // 拿到对象所有的键名
                const keys = Object.keys(this);
                let i = 0
                // 设置迭代器
                return {
                    next : () => {
                        const propName = keys[i];
                        const propValue = this[propName];

                         var result = {
                            value :  {
                                propName,
                                propValue
                            },
                            done : i++ >= keys.length

                        }
                        return result;
                    }
                }
            }
        }

生成器(generator)

什么是generator函数?
是一种ES6里面提供的一种方法 他是yield标识符和next方法调用 作用是可以是函数分段调用
怎么使用生成器?

 function* love() {
            yield "1";
            yield "2";
            yield "3";
            return "over"
        }
       var loves = love();
        console.log(loves.next());
        console.log(loves.next());
        console.log(loves.next());
        console.log(loves.next());
        console.log(loves.next());

输出为:
在这里插入图片描述

调用next方法之后的逻辑 :
1.当函数调用next方法之后 在函数内部遇到了yield关键字 函数就会暂停执行 next方法的返回值就是yeild 后面接的数据
2.当我们再次调用next方法时 就会从当前暂停的位置继续往下走 直到遇到下一个yield
3.运行到最后 没有yield关键字 就会一直往后执行 直到遇到return 关键字 返回的是return后面的值 并且状态变成true
4.最后没有遇到return 返回值为undefined 状态值为true
generator函数的特性 :

  1. generator函数是分步执行的 以yield 为标志 表示函数暂停执行 通过调用next方法恢复函数执行
  2. generator函数的写法跟普通函数有区别 在function关键字和函数名之前加一个* 通常情况下 *紧挨着function写
  3. generator函数直接调用 是不会执行函数体的 而是要调用next方法 才能往下执行
  4. generator函数调用之后 返回的值是一个iterator对象 只有调用next方法 才会迭代 进入下一个状态
    生成器 : 生成器指的是 通过构造函数Generator创建出的生成器对象 让函数可以分布执行 生成器也是一个迭代器 同时也是一个可以迭代的对象
    Async和 * 不能同时使用
    下面我们来看看数组的生成器
  var arr = [15, 16, 17, 19];
        function* createGenerator(arr) {
            for(const item of arr) {
                yield item;
            }
        }
        const iter = createGenerator(arr);
        console.log(iter.next());
        console.log(iter.next());
        console.log(iter.next());
        console.log(iter.next());
        console.log(iter.next());

结果为:
在这里插入图片描述

下面我们在看看生成器里面调用另外一个生成器

  function* f1() {
            yield 1;
            yield 2;
        }
        function* f2() {
            yield* f1(); // 在生成器内部调用其他的生成器  一定要在yield 后面加上*
            yield 4;
            // return 方法调用之后  就会提前结束生成器函数 整个迭代过程提前结束
            // return  9;
            // 可以在生成器内部抛出一个错误
            // throw 8;
            yield 5;
            yield 6;
        }
        const gener = f2();
        console.log(gener.next());
        console.log(gener.next());
        console.log(gener.next());
        console.log(gener.next());
        console.log(gener.next());
        console.log(gener.next());

结果为:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值