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}
- 与传统的方法对比:
传统的都是需要在修改的时候进行判断,而现在通过代理来处理,提升了代码的复用性和可维护性