ES6中的迭代器和生成器

迭代器

1.什么是迭代?
迭代就是将一种数据结构按照一定的顺序 不断取出的一个过程叫做迭代

2.迭代和遍历的区别?
迭代强调的是依次取出 不能保证把数据全部取出 也不能确定取出多少

3.什么是迭代器?
迭代器拥有获取下一个数据的能力 在返回的数据中有数据状态 是否继续往下迭代

4.js中规定的迭代器
js中规定 一个对象中 含有next方法 并且这个next方法返回一个对象 那么我们就认为这个对象为迭代器

下面我们就来看看迭代器相关的内容

迭代器(对象)

var obj  = {
            next() {
                // 用于拿到后面的数据
              return { 
                //   就是返回的数据 
                  value : "111",
                //   判断是否还有下一个数据
                  done : false
              }  
            }
        }

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

  let arr = [45, 15, 16, 18];

        // 数组的迭代器
        const iterator = {
            // 声明一个变量让它从0开始迭代
            i : 0,
            next() {

               var result =  {
                    value : arr[this.i],
                    // 设置迭代状态 (后面还有没有数据)
                    done : this.i >= arr.length 
                }

                this.i++;
                return result;
            }
        }

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

输出结果为:
在这里插入图片描述
每调用一次就会依次取出一个值,在这里大家可以发现return这是运用了闭包的原理。

接下来我们来试着封装一下自定义数组的迭代器

function createIterator(arr) {
            // 声明一个变量让它从0开始迭代
            let i = 0;
            return {
                next() {
                    var result = {
                        value: arr[i],
                        // 设置迭代状态 (后面还有没有数据)
                        done: i >= arr.length
                    }
                    i++;
                    return result;
                }
            }
        }
        var arr1 = [15, 18, 13, 17];
        var iter = createIterator(arr1);
        console.log(iter.next().value);//15
        console.log(iter.next().value);//18
        console.log(iter.next().value);//13
        console.log(iter.next().value);//17
        console.log(iter.next().value);//undefined

接着我们来封装个经典的斐波拉契
斐波拉契是 0,1,1,2,3,5…
即后面一个数为前两个数的和:

 function createFeiboIter() {
            // 定义数组初始值
            let pre1 = 1;
            let pre2 = 1;
            // 记录当前位置
            let n = 1;
            return {
                next() {
                    let value;
                    if (n <= 2) {
                        value = 1;
                    } else {
                        value = pre1 + pre2;
                    }
                    var res = {
                        value,
                        done: false // 不管它的结束值 只管next方法
                    }
                    // 换掉初始值
                    pre1 = pre2;
                    pre2 = res.value;
                    n++;
                    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 iter = arr[Symbol.iterator]();

对象设置迭代器

var obj = {
            a : 12, 
            b : 15,
            c : 19,
            [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;
                    }
                }
            }
        }
        for(const item of obj) {
            console.log(item);
        }

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

生成器(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、付费专栏及课程。

余额充值