ES6迭代器与生成器

目录

一,迭代器

二,生成器

三,小练习

四,作者语录

既然你知道路远,那从明天开始你就要早点出发。


一,迭代器

定义

迭代器(lterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署lterator接口,就可以完成遍历操作,ES6新增遍历方式for...of。

原生具备lterator接口的数据有:Array,Arguments,Set,Map,String,NodeList。

原理:创建一个指针对象,指向数据结构的起始位置,第一次调用==next()==方法,指针自动指向数据结构第一个成员,接下来不断调用next(),指针一直往后移动,直到指向最后一个成员,没调用next()返回一个包含value和done属性的对象.

举例说明:arr数组,本身就具有迭代器,用arr[symbol.iterator]();来取到这个接口

next()调用会返回一个包含value  done属性的对象,调用一次,指针指向一次,如果调用没有指向的类容,value返回undefined   done返回true来告诉接口后面指向没有值了

for of遍历可以迭代的数据类型,如果想要通过for of  遍历对象,首先想到迭代器,可以通过手动自定义去创建迭代器给对象,既可以遍历对象。

<script>
        const arr = ['王者荣耀', '吃鸡', '英雄联盟']
        let mylterator = arr[Symbol.iterator]();//数组本身就具备接口,拿到这个接口
        console.log(mylterator.next());//{value: '王者荣耀', done: false}
        console.log(mylterator.next());//{value: '吃鸡', done: false}
        console.log(mylterator.next());//  {value: '英雄联盟', done: false}
        console.log(mylterator.next());// {value: undefined, done: true}
        for(let value of arr){
console.log(value);
        }//王者荣耀 吃鸡 英雄联盟   for of遍历可迭代的数据类型
    </script>

应用:通过手动自定义给对象类型创建迭代器

 //迭代器接口的运用,,对象类型
        //手动自定义给对象类型创建迭代器接口
        const Person = {
            title: 'web2209',
            student: ['孙悟空', '猪八戒', '沙和尚'],
            [Symbol.iterator]() {
                let i = 0;
                return {
                    next: () => {
                        if (i < this.student.length) {
                            const Obj = { value: this.student[i], done: false };
                            i++;
                            return Obj;
                        } else {
                            return { value: undefined, done: true }
                        }
                    }
                }
            }
        }
//接收接口
const myiterator=Person[Symbol.iterator]();//接收迭代器
console.log(myiterator.next());//{value: '孙悟空', done: false}
console.log(myiterator.next());//{value: '猪八戒', done: false}
console.log(myiterator.next());//{value: '沙和尚', done: false
console.log(myiterator.next());//{value: undefined, done: true}没有指向的值,返回undefined  done  为true
    </script>

 

 注意:next()后面用的是箭头函数,而不是普通函数,这里的原因涉及this指向的问题,普通函数指向调用者,这里就不能使用this了,不然出错,改用箭头函数,应为箭头函数,this指向静态,根据上下文,具体是怎么定义的可以参考我前面的博客(this指向)

二,生成器

定义:

生成器本身是一个特殊的函数,生成器函数是ES6提供的一种异步编程解决方案,语法行为与传统函数不同。生成器函数function* xxx(){}

 <script>
        function * read() {
            console.log('执行第一次');
            yield '盛米'
            console.log('执行第二次');
            yield '洗米'
            console.log('执行第三次');
            yield '煮饭'
            console.log('执行第四次');

            yield '吃饭'
        }
        const myread=read();//生成器函数,返回一个迭代器对象   使用next()调用函数
        console.log(myread.next());
        console.log(myread.next());
        console.log(myread.next());
        console.log(myread.next());
        console.log(myread.next());
      

    </script>

生成器调用

执行生成器函数,返回的是一个迭代器对象,通过iterator.next()调用执行函数内语句,用yield 的分隔符让语句分段执行

生成器传参

概念:next('BBB')传入的参数作为上一个next方法的返回值


    <script>
        function* read(person) {
            console.log(person);
            console.log('执行第一次');
            let a1 = yield '盛米'
            console.log('执行第二次');
            let a2 = yield '洗米'
            console.log('执行第三次');
            let a3 = yield '煮饭'
            console.log('执行第四次');
            let a4 = yield '吃饭'
        }
        const myread = read('小红');//生成器函数,返回一个迭代器对象   使用next()调用函数
        console.log(myread.next());
        console.log(myread.next('a1'));
        console.log(myread.next('a2'));
        console.log(myread.next('a3'));
        console.log(myread.next('a4'));
    </script>

 注意生成器默认会为Symbol.iterator属性赋值,因此所有通过生成器创建的迭代器都是可迭代对象。 第一次调用next()方法时无论传入什么参数都会被丢弃。由于传给next()方法的参数会替代上一次yield的返回值,而在第一次调用next()方法前不会执行任何yield语句,因此在第一次调用next()方法时传递参数是毫无意义的。

三,小练习

<body>
    <div class="box">
        <P id="load"></P>
        <p id="message"></p>
        <button id="btn">加载数据</button>
    </div>
    <script>
        let load = document.getElementById('load');
        let message = document.getElementById('message');
        let btn = document.getElementById('btn');
        function step1() {
            setTimeout(() => {
                load.innerHTML = '数据加载中......'
                getinfo.next();
            }, 2000)
        }
        function step2() {
            setTimeout(() => {
                message.innerHTML = '好像断网了'
                getinfo.next();
            }, 2000)
        }
        function step3() {
            load.innerHTML = '';
            //   getinfo.next();
        }
        //生成器
        function* info() {
            let first = yield step1();

            let two = yield step2();

            yield step3();
        }
        const getinfo = info();//执行生成器函数,返回一个迭代器对象
        //点击加载
        btn.addEventListener('click', () => {
            getinfo.next();//调用
        })
    </script>
</body>

四,作者语录

既然你知道路远,那从明天开始你就要早点出发。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值