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

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)