Proxy
撰写时间:2024-11-05
修订时间:2024-11-05
拦截函数的调用
Proxy可为特定对象创建一个代理,并对其进行相应的拦截。
这个被代理的特定对象可以是一个函数,也可以是对象。如果被代理对象是函数,我们可以使用Proxy的apply方法对其拦截。但如果被代理对象是一个对象,而我们希望拦截其特定的一个方法,此时不能使用Proxy的apply方法进行拦截,因为我们先使用了诸如obj.greet的方式(尽管其是一个方法),将导致调用Proxy的get方法进行拦截。该方法主要是为拦截对象的属性而设立,要在其方法内拦截对象的方法,有点费劲(参见本站Canvas 2D概述的使用Proxy技术一节中的源代码)。
鉴于此,我们还是希望调用Proxy的apply方法来进行拦截。这需要一些额外的技巧。
现在,设有一对象:
这里只是简单地打印msg参数的信息。注意,此参数为可变长参数,因为console接受可变长参数。因此在这里使用可变长参数直白而合理。
接着,我们创建一个代理,只对obj.greet方法进行拦截。
要点一,apply方法的argsArray参数不是一个可变长参数,而是一个数组。因此,在我们进行拦截后,我们需要使用...newArray的方式,将数组转换为与obj的greet方法相对应的可变长参数。
要点二,使用Array的map方法来遍历并修改参数值,但该方法不会修改原来的数组,只是返回一个新的数组(详见map语法参考),因此我们在这里必须返回新的数组而不是原数组。
要点三,使用new Proxy(obj.greet, handler)的形式,代理对象不会拦截obj.greet,但会拦截obj.greet()。
最后,进行调用:
要点四,不能使用普通的proxy.greet()方式,因为这里代理对象为obj.greet,在其下面并没有greet方法。因此更好的变量名应为ObjGreetFuncProxy,但有点嫌长。
运行Demo。
