寒假学习——ES6(3)

寒假学习——ES6(3)

迭代器(iterator)

任何数据结构只要部署iterator接口,就可以完成遍历操作

  • for of循环
  • 原生具备该接口的数据(可用for of 遍历)
    • Array
    • Arguments
    • Set
    • Map
    • String
    • TypedArray
    • NodeList

for in保存的是键名,for of保存的是键值

  • 原理:创建一个指针对象指向数组起始位置,第一次调用next方法指针指向第一个成员,之后一个个移动去遍历,直到最后一个成员
  • 每次调用next方法的时候会返回一个包含value和done两个属性的对象
 <script>
            const fruit=['猕猴桃','菠萝蜜','香蕉'];
            let iterator=fruit[Symbol.iterator]();
            console.log(iterator.next());
    </script>

迭代器例子(自定义数据遍历)

 <script>
        const studio = {
            name: 'homyit',
            member: ['3qq', 'hh', 'll', 'tt', 'db', 'xx', ],
            [Symbol.iterator]() {
                let index = 0;
                let _this = this; //因为如果直接用this的话它的作用域是return那个大括号而不是整个这个对象,所以要用一个临时变量保存一下或者用箭头函数也行
                return {
                    //要返回一个next方法一个value属性,一个done属性
                    next: function () {
                        if (index < _this.member.length) {
                            const result = {
                                value: _this.member[index],
                                done: false
                            }
                            index++;
                            return result;
                        } else {
                            return {
                                value: undefined,
                                done: true
                            };
                        }
                    }
                }
            }
        }

        //对对象的那个成员属性进行遍历
        for(let i of studio){
            console.log(i);
        }
    </script>

生成器

  • 本质:就是一个特殊的函数
  • 作用:异步编程
  • 声明形式:function * 函数名(参数){函数体}
  • 执行语句直接调用不会执行要通过next方法
  • 函数代码分隔符:yeild语句,后面+表达式或者自变量,将函数分成几段,分别用几次next来执行
<script>
        function * gen(){
            console.log("第一个代码段");
            yield '1';
            console.log("第二个代码段");
            yield '2';
            console.log("第三个代码段");
            yield '3';
            console.log("第四个代码段");

        }
        let iterator=gen();
        //console.log(iterator);//返回一个迭代器对象
        iterator.next();//四次调用next分别输出四个代码段的输出语句内容
        iterator.next();
        iterator.next();
        iterator.next();
    </script>

如果单独调用next则输出分隔代码段的内容,如果打印这个next方法会发现next方法的value值就是yeild语句的内容

  • 生成器传参:
    • next的参数作为前一个yeild语句的返回值
<script>
        function * gen(args){
            console.log(args);
            let one=yield '第一个';
            console.log(one);
            let two=yield '第二个';
            console.log(two);

        }
        let ite=gen('aaa');//可以打印出实参
        ite.next();
        ite.next("第一个yeild语句的返回值");
        ite.next("第二个yeild语句的返回值");
    </script>
  • 生成器实例
  <script>
        //异步编程 文件操作 网络操作(ajax request) 数据库操作
        //实现1s后控制台输出111,2s后控制台输出222,3s后控制台输出333
        //本来是三层回调现在可以借助内嵌next方法实现
        function one(){
            setTimeout(()=>{
                console.log(111);
                ite.next();
            },1000)
        }
        function two(){
            setTimeout(()=>{
                console.log(222);
                ite.next();
            },2000)
        }
        function three(){
            setTimeout(()=>{
                console.log(333);
                ite.next();
            },3000)
        }
        function *gen(){
            yield one();
            yield two();
            yield three();
        }
        let ite=gen();
        ite.next();
    </script>

Promise

  • 实质:是一个构造函数可以实例化对象
  • 作用:用来封装异步操作并可以获取其成功或失败的结果
  • then方法:如果状态是成功调用参数的第一个回调函数,如果是失败调用第二个
<script>
        const p = new Promise(function (resole, reject) {

            setTimeout(function () {
                // let data = '用户数据';
                //     resolve (data);//让promise状态变成成功,通过then的第一个方法提取数据

                let err='数据读取失败';
                reject(err);//调用第二个函数参数

            }, 1000);
        }); //传入一个函数作为参数

        //调用promise对象的then方法,两个函数参数,如果上面调用了resolve这里就会执行then的第一个函数参数
        p.then(function (value) {
            console.log(value);
        }, function (reason) {
            console.log(reason);
        })
    </script>
  • Proomise封装读取文件
const fs=require('fs');
//两个参数一个路径一个函数
fs.readFile('./好好学习.md',(err,data)=>{
        if(err) throw err;
        console.log(data.toString());
});

//用Promise封装
const p=new Promise(function(resolve,reject){
        fs.readFile("./好好学习.md",(err,data)=>
        {
            //如果失败
            if(err) reject(err);
            //如果成功
            resolve(data);
        });

});
//通过then方法来指定回调
p.then(function(value){
console.log(value.toString());
},function(reason){
    console.log("读取文件失败");
});
  • Promise封装AJAX
 <script>
        const p = new Promise((resolve, reject) => {
            //1.创建对象
            const xhr = new XMLHttpRequest();

            //2.初始化
            xhr.open("GET","https://api.apiopen.top/getJoke");
            //3.发送
            xhr.send();
            //4.绑定事件,处理响应结果
            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4) {
                    //判断响应状态码
                    if (xhr.status >= 200 && xhr.status < 300) {//表示成功
                        resolve(xhr.response);
                    } else {
                        reject(xhr.status);
                    }
                }
            }
        });


        p.then(function (value) {
            console.log(value);
        }, function (reason) {
            console.error(reason);
        })
    </script>
  • Promise的then方法解析
    • 1.如果回调函数中返回的结果是非promise对象(包括没有返回值的情况此时为undefined),状态就是成功,返回值就是那个非promise对象
    • 2.是一个Promise对象返回该对象的内容
    • 3.抛出错误:
 <script>
        const p=new Promise((resolve,reject)=>{
            setTimeout(() => {
               // resolve("用户数据");
               reject('出错啦');
            }, 1000);
        });

        //调用then方法,该方法返回的值是Promise对象,对象状态由回调函数的执行结果决定

        const result=p.then(value=>{
            console.log(value);
            //return 'honghong'

            return new Promise((resolve,reject)=>{
                reject('error');
            })//如果then方法中的参数函数返回的是promise对象
            // throw new Error('出错了哦');
        },reason=>{
            console.warn(reason);
        })
        console.log(result);
    </script>
  • 因为then方法返回结果是Promise所以可以链式调用
 p.then(value=>{},reason=>{}).thenthen(value=>{},reason=>{})

集合与API

  • Set集合
  • 实质:是一种新的数据结构类似于数组
  • 实现了iterator接口可以用扩展运算符和for of进行遍历
  • 属性与方法:
    • size:返回元素个数,相当于数组的length
    • add:增加一个新元素返回当前集合
    • delete:删除元素,返回boolean值
    • has:检测是否包含某个元素,返回布尔值
 <script>
        let s = new Set(); //可传参或者不传参
        let s2 = new Set(['apple', 'banana', 'apple']);
        console.log(s2);//会进行去重与数学中集合概念很像
        s2.add('orange');//同理可以对其他几个属性进行测试
    </script>
  • 例子
<script>
        //数组去重
       let arr1=['红红','橙橙','黄黄','绿绿','红红'];
        let result=[...new Set(arr1)];//数组
        console.log(result);

        //找交集
        let arr2=['橙橙','黄黄','绿绿','蓝蓝'];
        let result2=[...new Set(arr1)].filter(item=>{
           let s2=new Set(arr2);
           if(s2.has(item)){
               return true;
           }else{
               return false;
           }
        });
        console.log(result2);
        
        
    </script>

Map

  • 实质:一个新的数据结构,是键值对的集合,键可以是各种类型的值,对象也可以
  • 实现了iterator接口所以也可用扩展运算符和for of进行遍历
  • 相关属性和方法:
  • 在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Phoebe4/article/details/113486984