ES6 -Proxy & Reflect

1.Proxy:代理

扩展(增强)对象或方法的一些功能
作用:vue中拦截,预警,上报,扩展功能,统计,增强对象等
proxy 是设计模式一种,代理模式
 
语法
new Proxy(target,handler)
new Proxy(被代理的对象,对代理对象做什么操作)

handler={
set(){},//设置
get(){},//获取对象属性
deleteProperty(),//删除
has(),//是否存在这个属性
apply(),//调用函数处理
}
 
// 访问name之前,打印访问的属性名称
let obj={
    name:'aaa',
}
let newobj=new Proxy(obj,{
    // target:obj ,property:访问的属性
    get(target,property){
        console.log(target,property);//{name: "aaa"} "name"
        console.log(`访问了${property}属性`);//访问了name属性
        return target[property];
    }
});

console.log(newobj.name);//aaa

 

// 实现一个,访问一个对象的属性,默认不存在的时候返回undefined,
// 如果不存在提示警告信息

let obj={
    name:'aaa'
}
let newobj=new Proxy(obj,{
    get(target,property){
        if(!target[property]){
            // throw new Error(`${property}属性不在此对象上`);
            return 'fail'
        }
        return target[property];
    }
})
console.log(newobj.name);//aaa
console.log(newobj.as);//fail

 

// DOM.div()

const DOM=new Proxy({},{
    get(target,property){
        console.log(target,property);//{} "div"
        return function(attr={},...argus){
            console.log(attr,argus);//{id: "div1", class: "box"} (2) ["aaa", "123"]
            const el=document.createElement(property);
            // 添加属性
            for(let key of Object.keys(attr)){
                el.setAttribute(key,attr[key]);
            }
             // 添加子元素
            for(let value of argus){
                if(typeof value=='string'){
                    value=document.createTextNode(value);
                }
                el.appendChild(value);

            }
            return el;
        }
    }
});

let oDiv=DOM.div({id:'div1',class:'box'},'aaa','123',DOM.a({'href':'www.baidu.com'},'链接'));

console.log(oDiv);// <div id="div1" class="box">aaa123<a href="www.baidu.com">链接</a></div>

 

// set() 设置,拦截:设置一个年龄,整数且不超过 200
let obj=new Proxy({},{
    set(target,prop,value){
        console.log(target,prop,value);//{} "age" 1
        if(prop=='age'){
            if(!Number.isInteger(value)){
                throw new TypeError('必须为整数')
            }
            if(value>200||value<1){
                throw new RangeError('必须在1-200之间')
            }
        }
        target[prop]=value;
    }
});

obj.age=1;//{} "a" 123

 

// deleteProperty():删除,拦截

// has() 检测

let json={a:1,b:2}

let newJson=new Proxy(json,{
    deleteProperty(target,prop){
        console.log(target,prop);//{a: 1, b: 2}  "a"
        delete target[prop]
    },
    has(target,prop){
        console.log(target,prop);//{b: 2} "b"
        return prop in target;
        
    }

});

delete newJson.a;

console.log(newJson.a);//undefined

console.log('b' in newJson);//true

 

// apply() 拦截方法

function fn(){
    return 123;
}

let newFn=new Proxy(fn,{
    apply(){
        return 456;
    }
})

console.log(newFn());//456

2. Reflect 反射

  Reflect.apply(调用的函数,this指向,参数数组)
 
function sum(a,b){
    return a+b;
}

let newSum=new Proxy(sum,{
    // target:sum ,context:this指向,argus:参数
    apply(target,context,argus){
        console.log(target,context,argus);//== console.log(...arguments);
        return Reflect.apply(...arguments);
    }
});

console.log(newSum(2,3));//5

 

// 通过Reflect对象身上直接拿到语言内部东西

// Reflect.has()
console.log('assign' in Object);//true
console.log(Reflect.has(Object,'assign'));//true

// Reflect.deleteProperty()
let obj={a:1,b:2};
Reflect.deleteProperty(obj,'a');//== delete obj.a
console.log(obj);//{b: 2}

 

posted @ 2018-09-04 10:15  yuesu  阅读(167)  评论(0编辑  收藏  举报