Vue中的代理Proxy和$ref (2)

handler.getOwnPropertyDescriptor():在获取代理对象某个属性的属性描述时触发该操作,比如在执行Object.getOwnPropertyDescriptor(proxy, 'foo')

handler.defineProperty():在定义代理对象某个属性时的属性描述时触发该操作,比如在执行Object.defineProperty(proxy,'foo',{})

handler.has():在判断代理对象是否拥有某个属性时触发该操作,比如在执行'foo' in proxy

handler.get():在读取代理对象的某个属性时触发该操作,比如在执行proxy.foo

handler.set():在给代理对象的某个赋值时触发该操作,比如在执行proxy.foo = 1

handler.deleteProperty():在删除代理对象的某个属性时触发该操作,比如在执行delete proxy.foo

handler.ownKeys():在获取代理对象的所有属性键时触发该操作,比如在执行Object.getOwnPropertyNames(proxy)

handler.apply():在调用一个目标对象为函数的代理对象时触发该操作,比如在执行proxy()

handler.construct():在给一个目标对象为构造函数的代理对象构造实例时触发该操作,比如在执行new proxy()

Reflect对象拥有对应的可以控制各种元编程任务的静态方法。这些功能和Proxy一一对应。

下面的这些名称你可能看起来很眼熟(因为他们也是Object上的方法):

 

Reflect.getOwnPropertyDescriptor(..)

Reflect.defineProperty(..)

Reflect.getPrototypeOf(..)

Reflect.setPrototypeOf(..)

Reflect.preventExtensions(..)

Reflect.isExtensible(..)

这些方法和在Object上的同名方法一样。然后,一个区别在于,Object上这么方法的第一个参数是一个对象,Reflect遇到这种情况会扔出一个错误。

 

 

 

 

3.   陷阱代理

使用set陷阱验证属性

假设创建一个属性值是数字的对象,对象中每新增一个属性都要加以验证,如果不是数字必须抛出错误。为了实现这个任务,可以定义一个set陷阱来覆写设置值的默认特性。

set陷阱接受4个参数:

trapTaqget 用于接收属性(代理的目标)的对象

key 要写入的属性键(字符串或Symbol类型)

value 被写入属性的值

receiver 操作发生的对象(通常是代理)

Reflect.set()set陷阱对应的反射方法和默认特性,它和set代理陷阱一样也接受相同的4个参数,以方便在陷阱中使用。如果属性已设置陷阱应该返回true,如果未设置则返回false(Reflect.set()方法基于操作是否成功来返回恰当的值)

 

可以使用set陷阱并检查传入的值来验证属性值:

 

1 //set陷阱并检查传入的值来验证属性值

 2 let target = { name: "target" };

 3 let proxy = new Proxy(target, {

 4     set(trapTarget, key, value, receiver) {

 5         // 忽略已有属性,避免影响它们

 6         if (!trapTarget.hasOwnProperty(key)) {

 7             if (isNaN(value)) { throw new TypeError("Property must be a number."); }

 8         } // 添加属性

 9         return Reflect.set(trapTarget, key, value, receiver);

10     }

11 });

12 // 添加一个新属性

13 proxy.count = 1;

14 console.log(proxy.count); // => 1

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zypwgx.html