前言

在网络中,两台计算机非直接连接,代理是那个中转站
在JS中,代理是ES6新增的东西,是某个对象的替身,对目标对象的操作能够通过代理来完成
这有点像C++中的指针(保存着另一个对象的内存地址),但JS的代理是一个独立于目标对象的新对象
代理
通过Proxy构造函数创建,接受两个参数:目标对象和处理程序对象
let proxy = new Proxy(target, handler);
处理程序对象可以为空,意味着代理对接收到的操作不作任何处理,直达目标对象
let target = {
money: 10000
};
let proxy = new Proxy(target, {});
console.log(target.money); //10000
console.log(proxy.money); //10000
proxy.money += 10000;
console.log(target.money); //20000
handler对象接收到操作后,会调用包含的捕获器(trap)处理
trap是handler对象的方法,函数名已经给定,接受不同的参数,重建原始行为
不同的操作(访问目标对象的属性、对目标对象赋值、调用目标对象的成员函数等等)对应不同的trap:handler 对象的方法(MDN)
以get()捕获器举例,在获取属性值的时候会被调用,其参数有三个:target, property, receiver
,分别对应目标对象、要访问的目标对象的属性、代理对象
let handler = {
get(target, property, receiver) {
console.log("get the attribute value");
return target.money;
}
}
//10000
//get the attribute value
//10000
//get the attribute value
//20000
反射
当捕获的方法不简单时,重建原始行为会比较麻烦
JS内置了全局对象Reflect
,提供了同名方法,具有与被捕获方法相同的行为,并且所有属性和方法都是静态的
于是上面的代码我们能改成这样
let handler = {
get(target, property, receiver) {
console.log("get the attribute value");
return Reflect.get(...arguments);
}
}
代理是个“对象”
就需要注意this的值
let target = {
fun() {
console.log("this is target");
console.log(this === proxy);
}
}
let handler = {
get() {
console.log("this is proxy");
console.log(this === handler);
return Reflect.get(...arguments);
}
}
let proxy = new Proxy(target, handler);
target.fun();
proxy.fun();
//this is target
//false
//this is proxy
//true
//this is target
//true
在target对象的方法中,this值分为
- target对象(直接操作)
- proxy对象(经过代理)
在handler对象的方法中,this值为自身
可以怎么用
- 检查传入的参数,确保类型正确
- 为多个操作添加一个先决操作
- 设置权限
加油啊!
