1 回答
TA贡献1993条经验 获得超6个赞
拦截器中的Reflect.apply应该相当于调用sum.bind(ctx)。ctx是调用时的上下文对象,这里是undefined
这样你调用proxy(1,2)的返回值就相当于,Reflect.apply(...arguments)*2,也就是sum.bind(undefined)(1,2)。
阮大大有写到:
Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程。
Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。
我个人理解是,本来你能直接达到目标(直接调用sum),而现在你想访问对象会经过一个拦截层,你可以在调用前修改参数,也可以在调用后修改返回值(比如本例的*2)。
拦截器类似元编程,相当于修改语言特性的语法,比如本例就是对函数的apply机制进行修改,其他代理如get、set等相当于对对象的读写特性进行了修改,表面上看就好像语言特性被修改了。
看下这两个例子应该就能明白如何用Proxy来代理一个函数:
function sum(left, right) {
return (this.x || left) + right;
}
var twice = {
apply(target, ctx, args) {
console.log(ctx == obj);
return Reflect.apply(...arguments) * 2;
},
};
var proxy = new Proxy(sum, twice);
let obj = { test: "test", proxy, x: 33 };
console.log(obj.proxy(1, 2));
//true
//70
//可见ctx为执行环境this
var twice_changeParams = {
apply(target, ctx, args) {
args[1] = args[1] + 5;
return Reflect.apply(...arguments) * 2;
},
};
proxy = new Proxy(sum, twice_changeParams);
console.log(proxy(1, 2));
// 16
//16为sum(1,(2+5))*2 分别对输入和输出进行了拦截
//这就是拦截器的含义
添加回答
举报
