美文网首页
es6学习笔记整理(十一)Proxy和Reflect

es6学习笔记整理(十一)Proxy和Reflect

作者: 尤樊容 | 来源:发表于2018-03-12 16:28 被阅读11次
    Proxy的概念和基本使用

    Proxy代理,连接用户和对象中间最真实的层,真实对象不可见。
    用户拿的对象和对象直之间不能直接操作的,需要经过代理。在代理的层面可以根据不同的业务逻辑来做相应的处理。

    let obj = {
        time:'2018-03-09',
        name:'asd',
        _r:123
    };
    
    let people = new Proxy(obj,{
        //拦截对象属性的读取
        get(target, key){
            return  target[key].replace('2018','2019');
        },
        //拦截对象属性的设置
        set(target, key, value){
            //只能修改name属性,target就是obj
            if(key === 'name'){
                return target[key] = value;
            }else{
                return target[key];
            }
        },
        //拦截key in object的操作
        //判断当前对象中是不是有某个属性
        has(target, key){
            //只暴露name属性
            if(key === 'name'){
                return target[key];
            }else{
                return false;
            }
        },
        //拦截delete
        deleteProperty(target, key){
            if(key.indexOf('_') > -1){
                delete target[key];
                return true;
            }else{
                return target[key];
            }
        },
        //拦截Object.key, Object.getOwnPropertySymbols,Object.getOwnpropetyNames
        ownKeys(target){
            return Object.keys(target).filter(item=>item != 'time');
        }
    });
    
    console.log('get', people.time);//2019-03-09
    
    people.time = '2019';
    console.log('set1', people.time);//2019-03-09
    
    people.name = 'qwe';
    console.log('set2', people.time, people);//2019-03-09 Proxy {time: "2018-03-09", name: "qwe", _r: 123}
    
    console.log('has','name' in people,'time' in people);//has true false
    
    console.log('ownKeys', Object.keys(people));//ownKeys (2) ["name", "_r"]
    
    delete people.time;
    console.log('delete',people);//delete Proxy {time: "2018-03-09", name: "qwe", _r: 123} 无法删除
    
    delete people._r;
    console.log('delete',people);//delete Proxy {time: "2018-03-09", name: "qwe"}
    }
    
    Reflect的概念和基本使用

    Reflect和Proxy的使用方法一样,Proxy有的方法,Reflect也都有,而且名称和用法也一样。

    let obj = {
        time:'2018-03-09',
        name:'asd',
        _r:123
    };
    
    console.log('Reflect get',Reflect.get(obj, 'time'));//Reflect get 2018-03-09
    Reflect.set(obj,'name','qwe');
    console.log('Reflect set', obj);//Reflect set {time: "2018-03-09", name: "qwe", _r: 123}
    
    console.log(Reflect.has(obj,'name'));//true
    
    Proxy和Reflect的适用场景

    实际运用: 对数据校验,比如手机号、邮箱等

    function validator(target, validator){
        return new Proxy(target,{
            _validator:validator,
            set(target,key,value,proxy){
                if(target.hasOwnProperty(key)){
                    let va = this._validator[key];
                    if(!!va(value)){
                        return Reflect.set(target,key,value,proxy);
                    }else{
                        throw Error(`不能设置${key}到${value}`);
                    }
                }else{
                    throw Error(`${key} 不存在`);
                }
            }
        });
    
    }
    
    const personValidators={
        name(value){
            return typeof val === 'string';
        },
        age(val){
            return typeof val === 'number' && val>18;
        }
    };
    
    class Person{
        constructor(name, age){
            this.name = name;
            this.age = age;
            return validator(this, personValidators);
        }
    }
    const person = new Person('zhangsan', 18);
    //            person.name = 123;//类返回的是代理,代理里面有筛选和判断
    person.age = 80;
    console.log(person);//Proxy {name: "zhangsan", age: 80}
    
    
    • 与传统的方法对比:
      传统的都是需要在修改的时候进行判断,而现在通过代理来处理,提升了代码的复用性和可维护性

    相关文章

      网友评论

          本文标题:es6学习笔记整理(十一)Proxy和Reflect

          本文链接:https://www.haomeiwen.com/subject/zqndfftx.html