当前位置: 首页 > 科技观察

借鉴Vue3源码Proxy&Reflect

时间:2023-03-13 01:07:23 科技观察

这两个函数出现在ES6中,两者配合得很好!Proxy**proxy**是一个外来物,他没有任何属性!它封装了一个对象的行为。它需要两个参数。consttoto=newProxy(target,handler)**target:**指的是将被代理/包装的对象**handler:**是代理的配置,它会拦截对目标的操作(get,set,等)感谢代理,我们可以创建这样的陷阱:consttoto={a:55,b:66}consthandler={get(target,prop,receiver){if(!!target[prop]){returntarget[prop]}return`This${prop}propdon'texistonthisobject!`}}consttotoProxy=newProxy(toto,handler)totoProxy.a//55totoProxy.c//Thiscpropdon'texistonthisobject!内部对象的每个“方法”都有自己的目标函数。这里是一个对象方法列表,相当于进入Target:objectmethodtargetobject[prop]getobject[prop]=55setnewObject()constructObject.keysownKeys目标函数的参数可以根据不同的函数改变。例如,get函数取(target,prop,receiver(代理本身))和set函数取(target,prop,value(toset),receiver)。我们可以创建私有属性。consttoto={name:'toto',age:25,_secret:'***'}consthandler={get(target,prop){if(prop.startsWith('_')){thrownewError('Accessdenied')}returntarget[prop]},set(target,prop,value){if(prop.startsWith('_')){thrownewError('Accessdenied')}target[prop]=value//set方法返回布尔值//so让我们知道该值是否设置正确!返回真},ownKeys(target,prop){returnObject.keys(target).filter(key=>!key.startsWith('_'))},}consttotoProxy=newProxy(toto,handler)for(constkeyofObject.keys(proxy1)){console.log(key)//'name','age'}ReflectReflect是一个静态类,简化了proxy的创建。每个内部对象方法都有自己的Reflect方法objectmethodReflectobject[prop]Reflect.getobject[prop]=55Reflect.setobject[prop]Reflect.getObject.keysReflect.ownKeys?为什么要用呢?因为它与Proxy配合得很好!它接受与代理相同的参数!consttoto={a:55,b:66}consthandler={get(target,prop,receiver){//等价于target[prop]constvalue=Reflect.get(target,prop,receiver)if(!!value){returnvalue}return`This${prop}propdon'texistonthisobject!`},set(target,prop,value,receiver){//等价于target[prop]=value//Reflect.setreturnsbooleanreturnReflect.set(target,prop,receiver)},}consttotoProxy=newProxy(toto,handler)这样可以看出Proxy和Reflectapi很有用,但是我们不是天天用,用来做陷阱或者隐藏一些对象的属性,可能会不错使用它。如果你使用的是Vue框架,尝试修改组件的props对象,会触发Vue的warninglog,这个功能就是要用到Proxy:)!.to/codeoz/proxy-reflect-api-in-javascript-51la