ES6中的代理Proxy和反射Reflect

正如Proxy的英译"代理"所示,Proxy是ES6为了操作对象引入的API。它不直接作用在对象上,而是作为一种媒介,如果需要操作对象的话,需要经过这个媒介的同意

使用方式

/* @params

** target:⽤Proxy包装的⽬标对象

** handler:⼀个对象,对代理对象进⾏拦截操作的函数,如set、get*/

let p = newProxy(target,handler)

常用方法

get读取

set设置

has判断key是否存在

deleteProperty拦截delete

ownKeys拦截Object.keys等

{
    proxy
    let account = {
        id:9999,
        name:'admin',
        phone:'12345678909',
        create_time:'2021-10-13',
        _private:'demo'
    }

    let accountProxy = new Proxy(account,{
        // 拦截读取
        // 手机号中间四位变成****;创建时间改为2021-10-00
        get:function(target,key){
            switch(key){
                case 'phone':
                    return target[key].substring(0,3)+'****'+target[key].substring(7)
                    break;
                case 'create_time':
                    return target[key].replace('2021-10-13','2021-10-00')
                    break;
                default:
                    return target[key]
                    break;
            }
        },
        // 拦截设置
        // id不可更改
        set:function(target,key,value){
            if(key === 'id'){
                return target[key]
            }else{
                return target[key] = value
            }
        },
        // 判断key是否存在
        has:function(target,key){
            if(key in target){
                console.log(`${key}:${target[key]}`);
                return true
            }else{
                console.log('没有这个属性');
                return false
            }
        },
        // 拦截delete
        // _开头的为私有属性,不可删除
        deleteProperty:function(target,key){
            if(key.indexOf('_')===0){
                console.warn('私有属性,不可删除');
                return true //代表该方法执行成功,如果返回false代表方法执行失败
            }else{
                delete target[key]
                return true
            }
        },
        // 拦截Object.key() 
        // 如果是id或者是私有属性就不输出
        ownKeys(target){
            return Object.keys(target).filter(item=>{
                return item !== 'id' && item.indexOf('_') !== 0
            })
        }
})

    console.log('拦截读取',accountProxy.phone,accountProxy.create_time);
    accountProxy.id = 1234;
    accountProxy.name = 'xiaoming'
    console.log('拦截设置',accountProxy.id,accountProxy.name);
    console.log('拦截has','gender' in accountProxy);
    console.log('拦截has','name' in accountProxy);
    console.log('拦截delete',delete accountProxy['_private']);
    console.log('拦截delete',delete accountProxy['name']);
    console.log(accountProxy);
    console.log(account);
    console.log('拦截Object.keys()方法',Object.keys(accountProxy));

Reflect

与Proxy相同,ES6引入Reflect也是用来操作对象的,它将对象里一些明显属于语言内部的方法移植到Reflect对象上,它对某些方法的返回结果进行了修改,使其更合理,并且使用函数的方式实现了Object的命令式操作

Reflect.set(target, propertyKey, value[, receiver])//如果遇到 setterreceiver则为setter调用时的this

Reflect.has(obj, name)是 name in obj 指令的函数化,用于判断对象中是否有某一个属性, 返回值为布尔值

  // Reflect
    let obj = {
        name:'xiaoming',
        age:19,
        gender:'man',
        hobbies:'xxxxxxxx'
    }

    console.log('hobbies',Reflect.get(obj,'hobbies'));
    Reflect.set(obj,'name','Jim')
    console.log('obj',obj);
console.log('has',Reflect.has(obj,'name'));

    let exam = {
        name: 'Tom',
        age: 19,
        get info() {
            return this.name + this.age
        }
    }
    console.log(Reflect.get(exam, 'info'));//Tom19
    console.log(Reflect.get(exam, 'name'));//Tom
    // 当target对象中存在get方法,如果有receiver则this指向receiver
    let receiver = {
        name:'Jim',
        age:20
    }
    console.log(Reflect.get(exam,'info',receiver));//Jim20

使用Proxy与Reflect实现简单的双向数据绑定

获取dom对象

设置代理对象

配置代理选项

添加事件

实现双向数据绑定

 // 获取dom元素
    const txt = document.getElementById('txt')//span
    const inp = document.querySelector('#inp');//input

    // 初始化代理对象
    const obj = {}
    // 代理选项
    const handle={
        get(target,key){
            console.log('get');
            return Reflect.get(target,key)
        },
        set(target,key,value){
            if(key === 'text'){
                inp.value = inp.value === value?inp.value:value
                txt.innerHTML = value
            }
            return Reflect.set(target,key,value)//更新OBJ
        }
}

    let objProxy = new Proxy(obj,handle)
    inp.addEventListener('keyup',function(e){
        objProxy.text = e.target.value
        console.log(obj);
    })
    objProxy.text = 1234567890

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值