Proxy:代理 类比到实际生活中有供应商,代理商,客户,这里的Proxy就是代理商 ;在程序中就是连着用户和最真实的对象或者说原始数据的中间层;
Reflect:反射 反射Object
Reflect和Proxy的方法是一模一样的
实例演示Reflect和Proxy使用:
{
//类似于供应商的原始数据对象
let obj= {
time : '2017-03-11' ,
name : 'net',
_r : 123
};
// Proxy(原始数据对象,中间对原始数据做的操作);
let monitor = new Proxy( obj, {
//代理的操作,拦截对象属性的读取
get( target, key){
return target[key].replace('2017','2018');
},
//设置属性
set(target, key, value){
if(key === 'name'){
return target[key] = value;
}else{
return target[key];
}
},
//拦截key in object操作
has(target,key){
//只有是“name”才返回是否真的存在的值,其他全部返回false
if(key === 'name'){
returntarget[key];
}else{
return false;
}
},
//拦截delete
deleteProperty(target,key){
//只有key值是_开发才执行删除操作,其他的一律返回原始数据
if(key.indexOf('_')>-1){
delete target[key];
return true;
}else{
return target[key];
}
},
// 拦截 Object,keys , Obejct.getOwnPropertySymbols , Object.getOwnpropertyNames
ownKeys(target){
//过滤time属性
return Object.keys(target).filter(item=>item!='time');
}
});
//用户直接操作 monitor
// 获取属性直接调用get方法
console.log(monitor.time); // 2018-03-11
// 赋值操作会调用 monitor set方法
monitor.time = '2018';
monitor.name = 'xujing';
console.log(monitor); // {time: "2017-03-11", name: "xujing", _r: 123}
/// 使用in 调用has方法
console.log('name' in monitor, "time" in monitor ); // true false
// 删除操作直接调用deleteProperty方法
delete monitor.time;
console.log(monitor); // {time: "2017-03-11", name: "xujing", _r: 123} 没有删除
delete monitor._r;
console.log(monitor); // console.log(monitor); 数据被删除
console.log(Object.keys(monitor)); // ["name"] time过滤掉
}
{
let obj = {
time : '2017-03-11',
name : 'net',
_r : 123
};
console.log(Reflect.get(obj,'time')); // 2017-03-11
Reflect.set(obj,'name','xujing');
console.log(obj) ; // {time: "2017-03-11", name: "xujing", _r: 123}
console.log(Reflect.has(obj,'name'));// true
}
Reflect和Proxy使用场景:
在开发的工程中经常对一些数据进行校验,比如说年龄是不是满足什么样的条件,点击提交校验数据类型和格式等等。在数据类型校验的都会用到,实现与业务进行解耦。
{
function validator(target,validator){
return newProxy(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(val){
return typeof val === 'string';
},
age(val){
return typeof val === 'number'&& val>18;
}
}
classPerson{
constructor(name,age){
this.name = name;
this.age = age;
return validator( this, personValidators);
}
}
const person = new Person('lilei',20);
console.info(person);
person.name = 20;
console.info(person);
}
这种方式实现了实际数据,数据过滤方式,过滤操作的分离,方便后期的维护,代码复用性很高