ES6的前生今世

目录

目录

Promise是什么:

Promise基本用法:

使用Promise实现Ajax 

promise可以实现链式调用

Promise还可以并行调用

Proxy-代理

代理模式的逻辑 

ES6 的proxy代理

Proxy与Object.defineProperty()区别

class类


Promise是什么:

promise是解决回调地狱的一种异步编程解决的方案

promise可以理解为一个容器,容器内已经预设好了事件成功和失败的结果。

从语法上说,promise是一个对象,从它可以获取异步操作消息。

 ·promise有两个特点:

  1.  对象状态不受外界影响,promise有三种状态:

        pending 进行中

        fulfilled  已成功

        rejected 已失败

        只有异步操作的结果可以决定当前是什么状态,任何其他操作均无法改变这个状态,这也是            promise名字由来,它的英文意思就是“承诺”,其他手段无法改变

  2.一旦状态确定,不会改变,任何时候就是此结果。promise对象状态改变只有两个可能:

        pending ->fufilled   和   pending ->rejected

        只要这两种情况发生,状态凝固,不会改变,此时成为serolved(已定型),改变发生后                对promise添加回调,会立刻得到这个结果

Promise基本用法:

 // 基本用法
 // promise是一个构造函数,用来生成promise实例
 // promise作为构造函数,接收两个参数:resolve 和 reject,它们由js引擎提供,不用自己部署

 let promise = new Promise((resolve,reject)=>{})

 // resolve函数作用是将promise从pending转变为resolved,在异步成功操作后调用,并将异步成功结果作为 
 // 参数传递出去
 // reject函数作用是将promise从pending转变为rejected,在异步操作失败后调用,将异步报错结果作为
 // 参数传递出去

 let promise1 = new Promise((resolve,reject)=>{
	 if(异步操作成功){
		 resolve('success')  //异步成功操作后调用,并将异步成功结果作为参数传递出去
	 }else{
		 reject('error')     //异步操作失败后调用,将异步报错结果作为参数传递出去
	 }
 })	 

 //promise实例生成后,可以用then方法分别指定 resolved状态 和reject状态的 回调函数
 //promise1.then()
 //then方法可以接收里昂个回调函数作为参数,第一个是promise对象状态变成resolved,第二个是rejcet, 
 //其中第二个函数是可选的,非必须

 promsie1.then((res)=>{},error=>{})

使用Promise实现Ajax 


  //使用Promise实现Ajax
  const request = (type, url, data = null) => {
    const promise = new Promise((resolve, reject) => {
      const xmlHttp = new XMLHttpRequest()
      xmlHttp.open(type, url)
      if (type === 'GET') {
        xmlHttp.send()
      } else {
        xmlHttp.setRequestHeader('Content-type', 'application/json')
        xmlHttp.send(JSON.stringify(data))
      }
      xmlHttp.responseType = 'json'
      xmlHttp.onreadystatechange = function () {
      
        /* @0 - (未初始化)还没有调用send()方法
            1 - (载入)已调用send()方法,正在发送请求
            2 - (载入完成)send()方法执行完成,已经接收到全部响应内容
            3 - (交互)正在解析响应内容
            4 - (完成)响应内容解析完成,可以在客户端调用了 */
     
        if (xmlHttp.readyState !== 4) return
        if (xmlHttp.status === 200){
          resolve(xmlHttp.response)
        }else{
          resject('error')
        }
      }
    })
    return promise
  }

promise可以实现链式调用

        需求背景:当下一个请求需要上一个请求成功后的某个值当参数时

        链式调用,then时promise实力上的一个方法。当第一个请求成功时,promise状态为resolve(成功),成功return出第二个请求,然后第二个then方法调用第二个请求,以此类推。如果某个return的请求再then后失败,则会中止该then之后的then调用

   query: function (){
        request('get',`${this.url}/getOne`)
            .then(res => {
                //第一次调用成功后,返出第二个请求
                const { id ,type} = res ;
                if(type==='S'){
                    return request('get',`${this.url}/getTwo?id=${id}`)
                }
            })
            .then(res => {
                const { age, type } = res
                if(type==='S'){
                //第而次调用成功后,返出第三个请求
                    return  request('get',`${this.url}/getThree?age=${age}`)
                }
            })
            .then(res => {
                console.log(res)
            })
    }

Promise还可以并行调用

并行调用有两个方法,分别是Promise.all()和Promise.race()

Promise.all(),一次性发起所有请求,通过.then可以查看请求的所有结果,当所有请求成功时,Promise状态变为成功(fufilled)then可以查看所有请求成功的结果;当有某一个是失败(rejected),Promise状态变为失败,返回第一个失败的结果

Promise.race(),一次性发起所有请求,但是只能看到一个结果,这个结果的条件是:谁请求最快,就展示谁的,并将状态定义为这个结果的状态

            //Promise.all
            Promise.all([
                request('get',`${this.url}/getOne`),
                request('get',`${this.url}/getTwo`),
                request('get',`${this.url}/getThree`),
            ]).then(([a,b,c])=>{
                console.log(a,b,c)
            })
           //Promise.race
            Promise.race([
                request('get',`${this.url}/getOne`),
                request('get',`${this.url}/getTwo`),
                request('get',`${this.url}/getThree`),
            ]).then(a=>{
                console.log(a )
            })

Proxy-代理

可以理解为在目标对象之前架设一层拦截,外部所有的访问都必须先通过这层拦截,因此提供了一种机制,可以对外部的访问进行过滤和修改。这个词的原理为代理,在这里可以表示由它来“代理”某些操作,译为“代理器”。其作用体现在三个方面:

1.拦截和监视外部对对象的访问

2.降低函数或类的复杂度

3.在复杂操作前对操作进行校验或对所需资源进行管理

注意: 代理对象可以理解为明星的经纪人。(如下所示)

代理模式的逻辑 

		
			//声明女孩
			var girl = function(name) {
				this.name = name
			}

			//声明男孩
			var boy = function(girls) {
				this.girls = girls;
				this.sendFlower = function(flower) {
					return console.log(`hi${girl.name}:男孩送你一个礼物${flower}`)
				}
			}

            //声明代理女孩的 角色
			var proxyObj = function(girls) {
				this.girls = girls;
				this.sendFlower = function(flower) {
					(new boy(girls)).sendFlower(flower)
				}
			}
            
            // 代理实例化
			var proxy = new proxyObj(new girl('小美'))
			console.log(proxy)

			var a = proxy.sendFlower('9999玫瑰花')

ES6 的proxy代理

ES6原生提供了Proxy构造函数,用来生成Proxy实例。

       let target = { /*目标对象的属性*/ };              //目标对象
       let handler = { /*用来定制拦截操作*/ };        //拦截层对象
       let proxy = new Proxy(target, handler);   

 

Proxy 对象的所有用法,都是上面这种形式,不同的只是handler参数的写法(所要使用的功能不同,写法不同)。
        new Proxy()表示生成一个Proxy实例,作为代理对象;
        target表示所要拦截的目标对象;
        handler声明了代理 target 的指定行为,表示一个用来定制拦截行为的对象。

handler有十三种方法如下:

		get(target, propKey, receiver):拦截对象属性的读取,比如proxy.foo和proxy['foo']。
		
		set(target, propKey, value, receiver):拦截对象属性的设置,比如proxy.foo = v或proxy['foo'] = v,返回一个布尔值。
		
		has(target, propKey):拦截propKey in proxy的操作,返回一个布尔值。
		
		deleteProperty(target, propKey):拦截delete proxy[propKey]的操作,返回一个布尔值。
		
		ownKeys(target):拦截Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、
						 Object.keys(proxy)、for...in循环,返回一个数组。该方法返回目标对象所有自身的属性的属性名,
						 而Object.keys()的返回结果仅包括目标对象自身的可遍历属性。
						 
		getOwnPropertyDescriptor(target, propKey):拦截Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。
		
		defineProperty(target, propKey, propDesc):拦截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。
		
		preventExtensions(target):拦截Object.preventExtensions(proxy),返回一个布尔值。
		
		getPrototypeOf(target):拦截Object.getPrototypeOf(proxy),返回一个对象。
		
		isExtensible(target):拦截Object.isExtensible(proxy),返回一个布尔值。
		
		setPrototypeOf(target, proto):拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。
		
		apply(target, object, args):拦截 Proxy 实例作为函数调用的操作,比如proxy(...args)、proxy.call(object, ...args)、proxy.apply(...)。
		
		construct(target, args):拦截 Proxy 实例作为构造函数调用的操作,比如new proxy(...args)。
		


 

        

Proxy与Object.defineProperty()区别

Proxy:

        优点:可以劫持整个对象,并返回一个新得对象,有13中劫持操作

        缺点:兼容性不好

Object.defineProperty()

        优点:可以更好的拦截

        缺点:无法监听数组下标的变化,导致直接通过数组下标设置值,不能实时响应(   虽说对常用方法进行了处理,但依然有局限性);只能劫持对象属性,因此需要对每个对象的每个属性进行遍历。    

class类

省流:ES6的class可以看作是一个语法糖,它的绝大部分功能ES5同样可以实现

ES5实现:

 
function setClass { 
    this.x = x
    this.y = y
}


 setClass.prototype.eat = function(){
    return this.x
}

var f = new setClass('鱼',20)

ES6实现:


	   class Person{
		   constructor(name,age) {
		       this.name=name;
			   this.age=age
		   }
		   action(){
			   return this.name
		   }
		   goTo(){
			   ...
		   }
	   }

ES6的calss继承方式:

//class的继承 extends关键字实现
class newPerson extends Person {
	constructor(args) {

		//super相当于是person.prototype.constructor.call(this)的实现
		//super作为函数调用时,代表父类的构造函数,ES6要求,子类的构造函数必须执行一次super
		super(args)
		const {
			name,
			age
		} = args
		this.name = name
		this.name = name
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值