ES6新特性使用小結(四)
阿新 • • 發佈:2017-10-02
aso 數據 定義 mon 過濾 != style nbsp com
十一、Proxy 、Reflect
①、Proxy 的概念和常用方法
{ let obj = { //1、定義原始數據對象 對用戶不可見 time: ‘2017-09-20‘, name: ‘net‘, _r: 123 }; let monitor = new Proxy(obj, { //2、通過Proxy新生成一個對象 映射obj 代理所有對obj的操作 //攔截對象的屬性讀取get(target, key){ //設置訪問規則 return target[key].replace(‘2017‘, ‘2018‘); }, 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: 123 }; // 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}
ES6新特性使用小結(四)