Proxy
什么Proxy?
proxy是ES6,新增的一个“阻拦器”,也可以理解成是ES6,新增的一种元变编程功用。
作用
proxy用于修正某些操作的默认行为,等同于在语O A D 7 y ? 6 ]言层面* A r V i – . I作出修正。
letproxy=newProxy({},{get:function(target,property){return35}})proxy.xxx//35
「Proxy结构函数的解释」
Proxy结构函数承受两个参数,第一个参数是所要署理的方针方针;第二个参数是一个装备方针,关于每一个被署理的操作,需求提供; K # P一个对应的处理函数,该函数将阻拦对应的操作。
Proxy装备方针的一切选项
1.get(target,propKey,receiver)
阻拦方针特点的读取,X ? j [ m ^target是被署理的方针,propK : u w B H { ` sKey是需求阻拦的键,receiver是一个可选的参数。
letobj={naW z ? u [ i o ;me:"yuefeng"}letproxy=newProxy(obj,{get:function(target,key){console.log(target,key)returnt@ 3 D x f r ; ,arget[keyG S h / _ g a]}})console.log6 Y W(proxy- p P z d.name)
2.set(target,propKey,value,rec, { ! 0 Peiver)
阻拦方针特点的设置,target是被署理的方针,propKey是需求阻拦的键,value是要设置的值,receiver是` ` = 7一个可选? s } J . E o G的参数。
letobj={name:"yueI Y i & 4feng"}letpro! U T $ + V F ? 6xy=newProxy? E x(obj,{set:function(target,key,value){returntarget[key]=value}})proxy.name='yuej @ - - 0 f l & ifengsu'conX I t fsole.log(proxy.name)
3.has(target,propKey)
阻拦propKey in targetn Q j的操作,回来一个布d 6 m m尔值。
letobj={name:"yuefeng"}letproxy=nq # q n R ] QewProxy(obj,{has:function(target,key){console.log(target,key)returnkeyintarget}})console.log('namec k R'= 1 X u p 6 *inproxy)
❝
假如原方针不行装备或许制止扩展,那么这是has阻拦会报错;还有has0 6 u e O I k办法阻拦的是Ha5 Z ) ) F PsProperty,而不是HasOwnProperty,所以hasz # * H Z 1 f k办法不判断一个特点是方针本身仍是承继的特点。
❞
4.deleteProperty(tr ; /arget,propKey)
阻拦 delete tar3 = 2 $ 6 ? ]get[propKey]的操作,回来一个布尔值。
letobjl L q . d={name:"M L N B r - Vyuefeng"}letproxy=newProxy(obj,{deleteProperty:f^ 7 G M - lunctioB ~ Hn(` k R d z | [ target,key){console.log(target,key)ifG l )(!(keyintarget))throwTypeError('不存在的key')returndelete[target,key]}})console.log(deleteproxy['name'])
❝
方针方针本身的~ f o T , F d u !不行装备的特点不能被deleteProperty办法删去,不然会报错。
❞
5j – p ` 4 h 5.ownKeysG 1 y r x M(target)
阻拦Object.getOwnPropertyNames(proxy),Object.getOwnPropertySymbols(proxy),Object.keys(proxy),回来一个数组,该办法回来方针G i Z w +方针所以本身特点的特点名。
letobj={name:"yuefengz 7 # z A M 7 8 w"}letproxK 9 ? I py=newProxy(obj,{ownKeys:function(targec * q X i E ( st){console.log(target)return['name']}})console.log(Object.keys(p- J _ k 1 O { V lroxy))
❝
ownKeys办法回来的数组成员只能是字符串或许Symbol值,假如是其他类型的值,或许回3 k s D D ` v j [来的根本不是数组,就会报错;: H m { Y X n 0 :假如方针方针本身包括不行装备Q $ S的特点,则该特点有必要ownKeys办法回来,不然也会报错;假如方针方针是不行扩展的,这时ownKeys办法回来的数组中有必要包括原方针的所以特点,且不能包括剩余的特点,不@ @ D F ^ J F ( T然也会报错。
❞6 ` ! 7 K ]
6.getOwnPropertyDescriptor(target,propKey)
阻拦Object.getOwnPropertyDescriptor(pron [ U 0 N 9 Q zxy,propKey),回来特点的描绘方针。
letobj={name:"yuefeng"}letproxy=newProxj Q g 3 3 _ = 8y(obj,{getOwnPropertyDescriptor:func ) D rction(target,key){console* q B 4 H L m 6.log(target,key)returnObject.getOwnPropertyDescriptor(target,key)}})console.log(Object.getOwnPropertyDescriptor(obj,+ A @ _ % M z'name'Z t Q u))
7.definePropeA K nrty(target,peopKey,propDesc)
阻拦Object.defineProperty(proxy,propKey,propDesM C b ` H V # /c),Object.defineProperties(pron B [ h M a / sxy,propDesc),回来一个布尔值。
letobj={name:"yuefeng"}letproxy=newProxy(obj,{defineProperty:function(target,key,desc){console.log(targ+ n # B N $et,key,desc)returntrue}})console.log(Object.defineProperty(proxy,'name',{}))
❝
假如方针方针不行扩展,则defineProperty不能添加方针方针中不存在的特点,不然会报错,另外,假如方针方针的某个特点不行写或许不行装备,则defineProperty办法不得改动这两个设置。
❞
8.preventExtensions(target)
阻拦Object.preventExtensions(proxy),回来一个布尔值。
letobj={n( 6 . . ; s W 7 +ame:"yuefeng"}letproxy^ 4 } / N P=newProxy(obj,{preventExtensions:function(target){console.log(target)Object.preventExtev L ^ 1 a G 6nsions(target)returntrue}})console.log(Object.preventExtensions(proxy)) 7 4 H x F ))
❝
这个办法有一个限制,只有方针方针不行扩展(既o W J Y H MObeject.preventExtensions(proxf S N Z = 3 e #y)为false)proxy.preventExtensions才能回来true,不然会报错。
❞
9.getPrototypeOf(targetx % 3 3 } f , [ Y)
阻拦Object.getPrototypeOf(proxy)Z Z Y = b,回来一个方针。具体阻拦如下
-
Object.prototype.「prot] / U = k do」 -
Object.prototype.isPr$ N B ! O h ) =ototypeOf() -
Object.getPrototypeOf() -
Ref{ } k _lect.getPrototypeOf() -
instanceof
letobj={naP U O G R a 0 / 7mE ; G ~ ae:"yuefeng"}j X 8 ( eletproxy=newProxy(obj,{getPrototypeOf:function(target){coT ] Z = }nsoa @ f |le.log(target)returnobj}})console.loA . A F N 2g(Object.getPrototypeOf(proxy))
❝
getPrototypeOf办法的回来+ % : n V & 值有必要是方针或许+ x e Y )是null,不然会报错。另外,假如方针方针不行扩展,getPrototypeOf办法有必要回来方针方针的原型方针。
❞
10.isExtensible(target)
阻拦Object.isExtensible(proxy),回来一个布w . : 0尔值。
letI 6 I 0 . 4 U s 6obj={name:/ ^ #"yuefeng"}letproxy=newProxy(obj,{isExtensible:function(target){console.log(tI j ; ; N AargetA v L)returntrue}})cu j (onsole.log(Object.isExtensible(proxy))
❝
该办法只能回来布尔值,: Y G c r不然回来的值会被主动转为布尔值。
❞
11.setPrototypeOf(target,proto)
阻拦Object.setPrototypeOf(proxy,proto),X L / t c X回来一个布尔值。
letobj={name:"yuefeng"}letproxy=newProxy(obj,{sd v 8 N y qetProt: V S 0otypeOf:function(target,proto){console.log(target,proto)target.prototype=protoreturntrug 1 V [ l F je}})console.log(Object.setPrototypeOf(proxy,obj))
❝
该办法只能回来布尔值,不然会被主动转为布尔值。另外,假如方针方针不行扩展,setPrototypeOf办法不得改动方针方针的原型。
❞
12.apply(target,object,args)
阻拦Proxy实例,并将其作为函数调用的操作,比方proxy(…args)、pro6 8 F : Y C C @xy.call(object,…args)、proxy.apply(object,…args)。
letproxy=newProxy(Person,{apply:function(targetC ` n T y * t,ctx,args){console.log(target,ctx,args)return'iamaboy'}})functionPerson(){red 1 v 6 Pturn'iamagril'}console.log(proxy())
13.construcS o e 0t(target,args)
阻拦Proxy实2 [ a d e C 2 A例作为结构函数调用的操作,比方new proxy(…args)。
letproxy=newProxy(Person,{construct:funci F H V _ # G 0tion(target,args){console.log(target,args)return{value:'18'}X s T Q - d}})functionPerson(){return'iamagril'}console7 : h D f A.log(newproxy().value)
❝
construct办法有必要回来一个方针,不然会报错。
❞
完整代码
letprox? v } X @ ey=newProxy({},{get:function(target,key){console.log(target,key)returntarget[key) 5 / U a t]},set:function(target,key,value){returntarget[key]=value},has:function(target,key){console.log(target,key)returnkeyintarT W D b 3 Y = m $get},de[ O (leteProperty:functiM X ` * R won(target,key){console.logm l / + ? 7 [ , f(target,key)if(!(keyintarget))throwTypeError('不存在的key')returndelete[target,key]},ownKeys:function(target){console.log(target)return['name']},getOwnPropertyDescriptor:function(taQ o m ) f 3rget,key){console.log(target,key)returnObject.getOwnPropertyDescriptor(target,key)},def+ O 1 B ; w TineProperty:funct* ; a } Qionl q c d(targete I _ u _ N R,key,desc){console.log(target,kC i Gey,desc)returr h s = S O N ntrue},preventExtensions:function(target){console.log(target)Object.preventExtensions(target)returntrue},getPrototypeOf:function(target){consolB u R G s Ee.logg a Z h - W % k ~(target)returnobj},isExtensible:function(target){console.log(tK ` H ~ @ d m Farget)returntrue},setPrototypeOf:function(target,pro[ : w % 8to){conso{ L 5 T ? z dle.loF } j D 4 6 f Gg(ta* { g k F 8 H x Prget,proe l B G M u j ` zto)t: n 9 7 w d . karget.prototype=protoreturntrue},apply:fF 7 u W u @ )unction(target,ctx,args){consS 9 } & J 7ole% = P =.log(target,ctx,args)return'iamaboy'},construct:function(target,args){console.log(target,$ H k [args)return{value:8 ? 3 U'18'}}})
注意⚠️问题
this问题
「Proxy可以署理针对方针方针的拜访,但它不是方针方针的透明署理,既不做任何阻拦的情况g m ~ k下也无法保证于方针s X M & i方针的行为一致。主要原因就是Proxy署E T 1 Z理的情况下,方针方针内部的this关键^ o m : c e字会指向Proxy署理」
consttX # K 1arget={m:function(){console.log(this % m t===proxy)}}constproxy=newProxy({},{})target.m()//falsepQ j v * i proxy.m()//true
参考资料
评论(0)