Proxy详解

2020-04-01  本文已影响0人  仔崽06

概述

Proxy可以理解为,在目标对象之前设一层"拦截",外界对该对象的访问,都必须通过这层拦截,可以对外界的访问进行过滤和改写(表示可以用它"代理"某些操作,可以翻为“代理器")。

以上示例中所代理的目标对象是一个空对象,如果没有Proxy的介入,操作原来要访问的就是这个对象,第二个参数是一个配置对象,对于每一个被代理的操作,需提供一个对应的处理函数,该函数拦截对应操作.应为此示例配置对象有一个get方法来拦截对目标对象属性的访问请求.get方法的两个参数(target:目标对象,propKey:所访问的属性),可以看到访问此对象由于get没有设置访问属性统一返回35,所以访问任何属性都得到35。

以上示例由于handler是一个空对象,没有任何拦截,所以访问proxy就等同于访问target。

 以上示例表示Proxy也可以作为其他对象的原型,由于proxy对象是obj对象的原型,obj对象本身并没有time属性,所以会根据原型链,会在proxy对象上读取该属性,导致被拦截.

以上示例表示同一个拦截器,可以设置多个拦截操作。

Proxy拦截操作(13种)

1.get(target[被代理的对象],propKey[属性名],receiver[proxy实例本身]):拦截对象属性的读取,比如proxy.foo或proxy['foo']。

2.set(target[被代理的对象],propKey[属性名],value[新的属性值],receiver[proxy实例本身]):拦截对象属性的设置,比如proxy.foo=v或者proxy["foo"]=v,返回一个布尔值。

3.has(target[被代理的对象],propKey[属性名]):拦截propKey in proxy操作,返回一个布尔值

4.deleteProperty(target[被代理的对象],propKey[属性名]):拦截 delete proxy[propKey]操作,返回一个布尔值.

5.ownKeys(target[被代理的对象]):拦截object.getOwnPropertyNames(proxy),Object.getOwnPropertySymbols(proxy),Object.keys(proxy),for...in循环,返回一个数组。该方法,而object.keys()的返回结果仅包括目标对象资深可遍历的属性。

6.getOwnPropertyDescriptor(target[被代理的对象],propKey[属名]):Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。

7.defineProperty(target[被代理的对象],propKey[属性名], propDesc[描述符]):拦截Object.defineProperty(proxy,propKey,propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。

8.preventExtensions(target[被代理的对象]):拦截Object.preventExtensions(proxy),返回一个布尔值。

9.getPrototypeOf(target[被代理的对象]):拦截Object.getPrototypeOf(proxy),返回一个对象。

10.isExtensible(target[被代理的对象]):拦截Object.isExtensible(proxy),返回一个布尔值。

11.setPrototypeOf(target[被代理的对象], proto[原型对象]):拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。

12.apply(target[被代理的对象], object[对象this指向], args[参数]):拦截Proxy实例作为函数调用的操作,例如:proxy(...args),proxy.call(object,...args),proxy.apply()。

13.construct(arget[被代理的对象],args[参数]):拦截Proxy实例作为构造函数调用的操作,比如new proxy(...args)。

使用场景示例:

1.利用proxy,可以将读取属性的操作(get),转变为某个函数,从而实现链式操作。

2.实现私有变量

3.简单校验

Proxy.revocable()创建一个可撤销的Proxy对象.该对象的proxy属性是Proxy的实例,revoke属性是一个函数.当revoke函数执行后,在访问Proxy实例,就会报错.

上一篇下一篇

猜你喜欢

热点阅读