十一、Proxy 、Reflect

   ①、Proxy 的概念和常用方法

{
let obj = { //1、定义原始数据对象 对用户不可见
time: '2017-09-20',
name: 'net',
_r:
}; let monitor = new Proxy(obj, { //2、通过Proxy新生成一个对象 映射obj 代理所有对obj的操作
//拦截对象的属性读取
get(target, key){ //设置访问规则
return target[key].replace('', '');
},
set(target, key, value){ //设置修改规则
if (key === name) {
return target[key] = value; //只允许修改name
} else {
return target[key];
}
}, //拦截 key in object 操作
has(target, key){
if (key === 'name') {
return target[key]; //只暴露name属性
} else {
return false
}
}, //拦截对 delete 操作
deleteProperty(target, key){
if (key.startsWith('_')) { //只允许删除以 '_'开头的属性
delete target[key];
} else {
return target[key];
}
}, //拦截Object.keys(),Object.getOwnPropertySymbols(),Object,getOwnPropertyNames() 等方法
ownKeys(target){
return Object.keys(target).filter(item=>item != 'time'); //过滤掉 time 属性
}
});
//3、用户访问的是 monitor
console.log('get', monitor.time); //get 2018-09-20 读取的数据被代理修改了
monitor.time = '2018-01-15';
monitor.name = 'com';
console.log('set', monitor.time, monitor.name); //set 2018-09-20 net time属性的修改无法生效 console.log('has', 'name' in monitor, 'time' in monitor); //has true false time属性被我们拦截了 delete monitor.time;
delete monitor._r;
console.log('delete', monitor); //delete Proxy {time: "2017-09-20", name: "net"} _r属性被删除 而对time的操作被拦截 console.log('ownKeys', Object.keys(monitor)) //ownKeys ["name"] time属性被拦截
}

  ②、Reflect 的概念和用法

{              **同Proxy
let obj = {
time: '2017-09-20',
name: 'net',
_r:
};
// Reflect.get/set/has/ownKeys...(target,key,value);
console.log('Reflect get', Reflect.get(obj, 'time')); //Reflect get 2017-09-20 console.log('Reflect set', Reflect.set(obj, 'name', 'com'), obj);
//Reflect set true {time: "2017-09-20", name: "com", _r: 123} console.log('Reflect has', Reflect.has(obj, '_r')); //Reflect has true

  ③、使用 Proxy 和 Reflect 实现业务的解耦

function validator(target, validator) {
return new Proxy(target, { //返回一个对target的代理
_validator: validator, //接收 验证规则
set(target, key, value, proxy){ //定义 对 target的 修改规则
if (target.hasOwnProperty(key)) { //判断 target 的 key 是否存在
let vali = this._validator[key]; //去除对应key 的验证规则
if (!!vali(value)) {
return Reflect.set(target, key, value, proxy);
} else {
throw Error(`无法设置${value}到${key}`);
}
} else {
throw Error(`${key}不存在`)
}
}
});
}
const userValidator = { //定义验证规则
name(val){
return /[a-zA-Z0-9_]{3,12}/.test(val);
},
phone(val){
return /^1[3|4|5|8][0-9]\d{4,8}$/.test(val)
}
} class User{
constructor(name,phone){
this.name=name;
this.phone= phone;
return validator(this,userValidator); //得到一个 user的代理对象
}
}
let u = new User(); //初始化 得到 user 的代理
//u.name = 'a' //不符合 验证规则 抛出错误 无法设置a到name
console.log(u.name='Lain',u.phone=13797154666,u); //Proxy {name: "Lain", phone: 13797154666}

最新文章

  1. 当AngularJS POST方法碰上PHP
  2. Core 1.0中publishOptions Include的bug
  3. 获取当前时间 和 10s倒计时案例
  4. Split Array Largest Sum
  5. IOS第18天(8,核心动画转场动画)
  6. MySQL中select * for update锁表的问题
  7. kaptcha随机验证码的使用详解,超实用
  8. zabbix电话告警V1
  9. android用异步操作AsyncTask编写文件查看器
  10. perf---LINUX内核研究
  11. Codeforces Round #258 (Div. 2/C)/Codeforces451C_Predict Outcome of the Game(枚举)
  12. 事件拦截,仿qq侧拉的操作中
  13. Computation expressions and wrapper types
  14. Spring - IOC简介
  15. Spark1.4从HDFS读取文件运行Java语言WordCounts并将结果保存至HDFS
  16. pip安装mysql-python报错:Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-enRreC/mysql-python/
  17. nginx+lua的基本原理概念介绍
  18. Java Scanner学习记录
  19. TiDB数据库 mydumper与loader导入数据
  20. 菜鸟学Java(十)——分页查询

热门文章

  1. 分享知识-快乐自己:Struts2文件上传及文件下载
  2. 搭建LoadRunner中的场景(三)场景的执行计划
  3. POJ2155 Matrix(二维树状数组||区间修改单点查询)
  4. Godot-3D教程-02.3D性能和局限性
  5. [转载]理解 I/O Completion Port (IOCP完成端口)
  6. AtCoder Regular Contest 072 E:Alice in linear land
  7. mysql备份并升级sql语句
  8. HDU4027(线段树单点更新区间)
  9. 机器学习、图像识别方面 书籍推荐 via zhihu
  10. 反射-Class