1. 程式人生 > >ES6新特性使用小結(四)

ES6新特性使用小結(四)

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新特性使用小結(四)