ES6语法 3(class,迭代器,promise,generator,async/await,proxy/reflect)

1.Class类

es6中引入类的概念,作为对象的模板,使对象原型的写法更清晰更像面向对象编程。
es6中的class可以看作语法糖(计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用),他的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已

1.1构造函数

constructor 构造函数,为类的默认方法;
通过new命令生成对象实例时,会自动调用该方法。

一个类中必须有constructor方法,如果没有在类中显示定义构造函数,则一个空的constructor方法将会被默认添加到类中。

1.2实例属性和方法

定义在类体中的属性称为实例属性,定义在类体中的方法称为实例方法

不推荐在实例上定义方法,因为这样做方法会创建在实例上。

1.3原型属性和方法

原型属性和方法就是在构造函数的原型对象上存在的属性和方法。

不推荐在实例上定义属性,因为这样做属性的值无法自定义。

1.4静态属性和方法

通过static关键字来定义静态属性和静态方法。

静态属性和静态方法是定义在类上的,所以可以通过类直接访问。

在静态方法中,this指向当前类。

	class Animal{
	    //静态属性
	    static num=0;
	    //构造函数
	    constructor(name,age){
	        //实例属性
	        this.name=name;
	        this.age=age;
	        //实例方法(在这里设置的方法,每个实例创建时,方法会被重复创建),不推荐使用
	        // this.sayName=function(){
	        //     console.log(this.name);
	        // }
	        Animal.num++;//静态属性 构造函数执行一次num加1
	    }
	    //原型方法(Animal.prototype.sayName)
	    sayName(){
	        console.log(this.name);
	    }
	    //原型属性(在这里设置属性,在实例创建时不能被定义),不推荐使用
	    //color='red';
	    //静态方法
	    static getNum(){
	        console.log(Animal.num); //创建该类实例的次数
	    }
	}
	var a1=new Animal('xiaobai',2); //生成对象实例
	var a2=new Animal('xiaohei',3);
	console.log(a1);
	a1.sayName();
	Animal.getNum();

1.5继承

可以通过extends关键字实现继承,子类中可以没有构造函数,系统会默认提供一个。
子类如果提供了构造函数就必须显示调用super

class 作为构造函数的语法糖,同时有prototype属性(函数才有的属性)和__proto__属性(每个对象都有的属性),因此同时存在两条继承链

  1. 子类的__proto__属性,表示构造函数的继承,总是指向父类。
  2. 子类prototype属性的__proto__属性,表示方法的继承,总是指向父类的prototype属性。

super 关键字
super作为函数调用时,代表父类的构造函数。
super作为对象时,在普通方法中,指向父类的原型对象

	class Animal{
	    //构造函数
	    constructor(name,age){
	        //实例属性
	        this.name=name;
	        this.age=age;
	    }
	    //原型方法(Animal.prototype.sayName)
	    sayName(){
	        console.log(this.name);
	    }
	    getAge(){
	        console.log(this.name+this.age+"岁了");
	    }
	}
	class Dog extends Animal{
	    constructor(name,age,color){
	        super(name,age);//跟之前call方法逻辑系相同 ,代表父类的构造函数
	        this.color=color;
	    }
	    sayColor(){
	        console.log(this.color);
	    }
	    sayAge(){
	        super.getAge(); //在子类方法中,super为对象,指向父类的原型属性
	    }
	}
	var d1=new Dog('xiaobai',2,'red');
	console.log(d1);
	d1.sayName();
	d1.sayColor();
	d1.sayAge();
	console.log(Dog._proto_); //隐式原型,指向父类  继承构造函数
	console.log(Dog.prototype._proto_===Animal.prototype); //指向父类的原型 继承原型方法

2.迭代器

迭代器(遍历器)iterator是一种访问机制,它是一种接口,为各种不同的数据结构提供统一的访问机制。
要想定义迭代器,必须为对象添加一个Symbol.iterator方法,这个方法必须返回一个迭代器(内部一个有next方法的对象)。

ES6中Iteartor的作用:
1)为实现了iterator接口的数据,提供统一的访问机制(for of循环)
2)数据内部成员按照一定的次序排列,通过调用.next()方法,指向下一个成员
3)供ES6中的for of 循环来消费

原始就具有迭代器接口的数据类型有:Array,Map,Set,String,argunments,NodeList

var arr=[1,2,3,4,5];
//可以使用for of 循环
var itr =arr[Symbol.iterator]();  //返回迭代器对象
console.log(itr.next());

自定义一个可迭代对象

var obj={
    data:[1,2,3,4,5],
    [Symbol.iterator](){
        var index=0;
        var _this=this;
        return{
            next(){
                //判断每一次next后是否还有值
                if(index<_this.data.length){
                    return { value: _this.data[index++], done: false }
                }else{
                    return { value: undefined, done: true }                }
            }
        }
    }
}
var itr=obj[Symbol.iterator]();
console.log(itr.next()); //{ value: 1, done: false }
console.log(itr.next());  //{ value: 2, done: false }
console.log(itr.next());	//{ value: 3, done: false }
console.log(itr.next());	//{ value: 4, done: false }
console.log(itr.next());	//{ value: 5, done: false }
console.log(itr.next());	//{ value: undefined, done: true }
console.log(itr.next());	//{ value: undefined, done: true }

3.promise

promise是异步编程的一种解决方案。
就是一个容器里保存这某个未来才会结束的事件(异步操作)的结果。

Promise对象代表一个异步操作有三种状态: pending(进行中)fulfilled(已成功)rejected(已失败)

状态发生改变之后就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)

Promise是一个构造函数,接受一个回调函数作为参数,回调函数的参数是resolvereject
分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数。resolve是将Promise的状态置为fullfiled,reject是将Promise的状态置为rejected。

原型方法

  • Promise.prototype.then() (只有一个参数时)当状态由pending变为fulfilled的时候异步操作成功)执行该回调函数(promise原型方法)

    Promise.prototype.then(onFulfilled [,onRejected ] ) 当Promise变成接受状态(fulfillment)时,onFulfilled 作为回调函数被调用,当Promise变成拒绝状态(rejection )时,onRejected作为回调函数被调用。第二个参数onRejected可以省略,则表示promise变为fulfilled时调用第一个参数作为回调函数。

  • Promise.prototype.catch() 当状态由pending变为rejected的时候(异步操作失败)执行该回调函数(promise原型方法)

  • Promise.prototype.finally() 在promise结束时,无论结果是fulfilled或者是rejected,都会执行指定的回调函数(promise原型方法)

      var pm=new Promise((resolve,reject)=>{ //new了一个promise对象,并没有调用,里面的函数就执行了,用Promise的时候一般是包在一个函数中,在需要的时候去运行这个函数
         //预测三秒后会下雨
         setTimeout(()=>{
             if(Math.random()>0.5){
                 resolve('下雨了')
             }else{
                 reject('没有下雨')
             }
         },3000);
     })
     }
     var pm2=new Promise((resolve,reject)=>{
         //预测三秒后会打雷
         setTimeout(()=>{
             if(Math.random()>0.5){
                 resolve('打雷了')
             }else{
                 reject('没有打雷')
             }
         },3000);
     })
     // var all_pm=Promise.all([pm,pm2]); //两个状态都成功才成功 
     
     // var all_pm=Promise.any([pm,pm2]); //一个状态都成功就算功 
     
     // var all_pm=Promise.race([pm,pm2]); //竞速 哪个承诺先成功就执行哪个
     
     var all_pm=Promise.allSettled([pm,pm2]);//所有承诺都执行完毕后,返回结果数组
     // [
     //     { status: 'fulfilled', value: '下雨了' },
     //     { status: 'rejected', value: '没有打雷' }
     //   ]
     
     all_pm.then((res)=>{ //承诺执行成功时
         console.log(res); //[ '下雨了', '打雷了' ]
     }).catch((err)=>{ //承诺执行失败时
         console.log(err);
     }).finally(()=>{ //无论是否成功,都会执行
     	console.log('测试了一次');
     })
    
  • Promise.all([p1,p2]) 当p1,p2状态都为fulfilled时候,该实例的状态才为fulfilled

  • Promise.any([p1,p2]) 只要p1,p2状态有一个变为fulfilled,该实例的状态为fulfilled

  • Promise.race([p1,p2]) 当p1,p2之中有一个实例率先改变状态,该实例的状态就跟着改变。

  • Promise.allSettled() ES11新增,所有的承诺都执行完毕后,返回结果数组

  • Promise.resolve() 用于将现有对象转化为Promise实例fulfilled状态

      var res = Promise.resolve('data')//promise对象
     res.then((res)=>{
         console.log(res);
     })
    
  • Promise.reject() 用于将现有对象转化为Promise实例rejected状态

     var err = Promise.reject(new Error('出错了!'));
     err.catch((err)=>{
         console.log(err);
     })
    

4.Generator

Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同.

Generator 函数是一个状态机,封装了多个内部状态

执行 Generator 函数会返回一个遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。

4.1特点

● function关键字与函数名之间有个星号
● 函数内部使用yield表达式
● 可以放置return语句,返回最终的结果Async

Generator 函数不会像普通函数一样立即执行,而是返回一个指向内部状态对象的指针,所以要调用遍历器对象Iterator 的 next 方法,指针就会从函数头部或者上一次停下来的地方开始执行。

function f1(){
return 1;
}
function* getData(){
	console.log("one");
     yield f1();
     console.log("two");
     yield 'xiaoming';
     return ‘3’
}
var res = getData();
console.log(res.next());  //one { value: 1, done: false }
console.log(res.next());  //two { value: 'xiaoming', done: false }
console.log(res.next());  //{ value: 3, done: true }
console.log(res.next()); //{ value: undefined, done: true }

第一次调用 next 方法时,从 Generator 函数的头部开始执行,先是打印了 one ,执行到 yield 就停下来,并将yield 后边表达式或函数的值作为返回对象的 value 属性值,此时函数还没有执行完, 返回对象的 done 属性值是 false。
第二次调用next方法时,generator函数接着上次执行的位置开始执行,打印two,遇到yield则停下来,将yield后的值作为返回对象的value值,函数没有执行完,返回对象的done值为false。
第三次调用next方法时,将return后的值作为返回对象的value值,函数执行完毕,返回对象的done值为true。
第四次调用next方法,函数已经执行完毕,返回对象value值为undefined,done值为true。

return方法

return 方法返回给定值,并结束遍历 Generator 函数。
return 方法提供参数时,返回该参数;不提供参数时,返回 undefined 。

res.next(); //one { value: 1, done: false }
res.return('2'); // {value:2,done:true} 结束generator函数
res.next(); //  { value: undefined, done: true }

4.2 作用

  • 交替执行

     function f1(){
         return 1;
     }
     function f2(){
         return 2;
     }
     function* getNum(){
         while(true){
             yield f1();
             yield f2();
         }
     }
     var res=getNum();
     setInterval(()=>{
         console.log(res.next());
     },1000)
     console.log(res.next());
     /*{ value: 1, done: false }
     { value: 2, done: false }
     重复执行*/
    
  • 顺序执行

  • 与promise结合实现对异步代码的顺序控制

     function f1(){
         return new Promise((resolve,reject)=>{
             setTimeout(()=>{
                 if(Math.random()>0.1){
                     resolve('下雨了2')
                 }else{
                     reject('没下')
                 }
             },1000)
         })
     }
     function* getData(){
         yield f1();
     }
     var res = getData();
     //console.log(res.next);
     res.next().value.then((res)=>{
     	console.log(res)
     });  //{value:promise,done:false}
    

5.Async

async 是 ES7 才有的与异步操作有关的关键字
Async函数是generator函数的语法糖.
Async函数的执行和普通函数一致,只需要一行代码即可,因为他具有内置的执行。
语法更加简单。

async函数

async function 函数名(参数){
函数体
}

返回值:
async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数。

async 函数中可能会有 await 表达式,async 函数执行时,如果遇到 await 就会先暂停执行 ,等到触发的异步操作完成后,恢复 async 函数的执行并返回解析值。

await 关键字仅在 async function 中有效。

await关键字

await 操作符用于等待一个 Promise 对象, 它只能在异步函数 async function 内部使用。

async function 函数名 (参数){
//函数体
var res = await expression
console.log(res)
}

expression:一个 Promise 对象或者任何要等待的值。

返回值

返回等待的promise对象的处理结果,若等待的不是promise对象,则直接返回值。
await等待的为promise对象,则暂停执行,等待promise对象执行完毕后,async函数继续执行。

特点

await关键字只在async函数内有效。
● async函数返回一个Promise 对象
● async函数可以实现也是一种异步函数同步化的实现

function xy(){
    return new Promise((resolve,reject)=>{
        //预测三秒后会下雨
        setTimeout(()=>{
            if(Math.random()>0.1){
                resolve('下雨了')
            }else{
                reject('没有下雨')
            }
        },3000);
    })
    }

/* (async function getData(){
    var res=await xy(); //等待承诺执行完毕
    console.log(res);
})() */ //相对于直接调用函数

async function getData(){
   var res =  await f1();
   console.log(res);
}
getData();

组合实例

function get(url){
return new Promise((resolve,reject)=>{
var x = new XMLHttpRequest;
x.open("GET",url,true);
x.send(null);
x.onreadystatechange =function(){
    if(x.readyState == 4 &&x.status==200){
        resolve(x.responseText)
    }else if(x.status!=200){
        reject(new Error('请求失败!'))
    }
}
})
}
var url = "http://81.69.24.232/pet/getArr.php";
function* getData(){
    yield get(url);
}
var res = getData();
res.next().value.then((res)=>{
    console.log(res);
});
(async function(){
   var res =  await getData(url);
   console.log(res);
})()

6.proxy/reflect

proxy我们可以理解为代理,其含义是在对象操作时,我们可以做一些额外的操作;
例如对数据的处理,对构造函数的处理,对数据的验证。

var obj={
    name:'xiaoming'
}
obj=new Proxy(obj,{
    get(target,key){
        return 'huang'+target[key];
    },
    set(target,key,value){
        return Reflect.set(target,key,value)
    }
})
obj.name='xiaohuang';
console.log(obj.name);

ES6基础
ES6语法 1(let,const,解构,模板字符串,扩展运算符)
ES6语法 2(函数,对象,数组功能新增,for of ,symbol,set,map集合)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值