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}