Proxy 有一个原始的数据对象,通过代理出来一个新的对象,用户操作的是这个新的对象
{
let obj ={ time:'2018-01-01', name:'lx' , _r:123 } let monitor = new Proxy( obj , { get(target , key){ //读取 return target[key].replace('2018','2017') //把值的2018改成2017 } set(target , key , value){ //设置 if( key === 'name'){ return target[key] = value } //只允许修改name else{ return target[key] } } has(target , key){ //拦截key in object if(key === 'name'){ return target[key] } else{ return false } } deleteProperty(target,key){ //拦截delete if(key.indexOf('_')>-1){ delete target[key] ; return true} else{ target[key] } } ownKeys(target){//拦截Object.keys,Objects.getOwnPropertySymbols,Object.getOwnPropertyNames等 return Object.keys(target).filter(item =>item!='time') } }) //用户看到和操作的是monitor console.log('get' , monitor.time) //2017-01-01 monitor.time='2019' console.log('set', monitor.time) //2017-01-01 console.log('has', 'name' in monitor , 'time' in monitor) //true false delete monitor.time console.log('delete', monitor) //time依然存在于monitor console.log('ownkeys', Objects.keys(monitor)); //,保护time不显示time }
Reflect
{ let obj ={ time:'2018-01-01', name:'lx' , _r:123 }; console.log( "get" , Reflect.get(obj,'time') ) //"2018-01-01" Reflect.set(obj,'name','lmx') ; console.log(obj) //{time: "2018-01-01", name: "lmx", _r: 123} console.log("has", Reflect.has(obj,'name') ) /true } //尽量不对object操作,而是使用Reflect来操作obj
例子:
obj.hasOwnProperty() 指出一个对象是否具有指定名称的属性
两个叹号主要是处理null/undifined/0/""等值,都能转换成布尔值
{ function validator(target,validator){ return new Proxy(target,{ _validator:validator, set(target,key,value,Proxy){ //判断当前对象是否有key值 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 personvalidator={ name(val){ 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 , personvalidator ) //返回的是个Proxy对象 } } const person = new Person(‘lx’,30); console.log(person) person.name = 48 //根据代码throw一个错误 }