Proxy Reflect

Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。

 1 {
 2     //类似于供应商的数据对象
 3     let obj = {
 4         time:'2019-12-13',
 5         name:'net',
 6         _r:123
 7     }
 8     //代理商
 9     let monitor = new Proxy(obj,{
10         //代理操作
11         //拦截对象属性的读取
12         get(target,key){  //target指代理对象,key是键值
13             return target[key].replace('2019','2020')
14         },
15         // 拦截对象设置
16         set(target,key,value){
17             if(key === 'name'){
18                 return target[key] = value;
19             }else{
20                 return target[key];
21             }
22         },
23         // 拦截 key in  object 操作
24         has(target,key){
25             if(key === 'name'){
26                 return target[key]
27             }else{
28                 return false;
29             }
30         },
31         // 拦截删除
32         deleteProperty(target,key){
33             if(key.indexOf('_') > -1){
34                 delete target[key];
35                 return true;
36             }else{
37                 return target[key]
38             }
39         },
40         // 拦截Object.keys,Object.getOwnPropertySymbols,Object.getOwnPropertyNames
41         ownKeys(target){
42             return Object.keys(target).filter(item=>item!='time')  //Object.keys(target)取出原始对象的key值
43         }
44     });
45     //用户直接操作minotor
46     console.log('get',monitor.time)
47 
48     monitor.time='2019';
49     monitor.name='sss';
50     console.log('set',monitor.time,monitor)
51 
52     console.log('has','name' in monitor,'time' in monitor)  //true false
53     
54     // delete monitor.time;
55     // console.log('delete',monitor)
56 
57     // delete monitor._r;
58     // console.log('delete',monitor)
59 
60     console.log('ownkeys',Object.keys(monitor))  //过滤属性
61 
62 }

Reflect

 1 {
 2     let obj = {
 3         time:'2019-12-13',
 4         name:'net',
 5         _r:123
 6     };
 7     console.log('reflect get',Reflect.get(obj,'time')); //Reflect 不需要new, get语法,对象,key值
 8     Reflect.set(obj,'name','bsq');
 9     console.log('set',obj)
10 
11     console.log('has',Reflect.has(obj,'name'))
12 }

实例运用

 1 {
 2     // 应用
 3     function validator(target,validator){
 4         return new Proxy(target,{
 5             _validator:validator,
 6             set(target,key,value,proxy){
 7                 if(target.hasOwnProperty(key)){
 8                     let va = this._validator[key];
 9                     if(!!va(value)){
10                         return Reflect.set(target,key,value,proxy);
11                     }else{
12                         throw Error(`不能设置${key}为${value}`)
13                     }    
14                 }else{
15                     throw Error(`${key} 不存在`)
16                 }
17             }
18         })
19     }
20     const personValidators={
21         name(val){
22             return typeof val === 'string'
23         },
24         age(val){
25             return typeof val ==='number'  && val>18
26         }
27     }
28     class Person{
29         constructor(name,age){
30             this.name=name;
31             this.age=age;
32             return validator(this,personValidators)
33         }
34     }
35     const person = new Person('lilei',30);
36     console.log(person)
37     // person.age='dd';
38     // console.log(person)   //index.js:9736 Uncaught Error: 不能设置age为dd
39     person.name='han meimei'
40     console.log(person)
41 }
posted @ 2019-12-17 15:33  木汐a  阅读(576)  评论(0编辑  收藏  举报