拦截并控制目标对象的交互
使用Proxy对象,我们可以使用多一层交互来控制对象。一个代理对象可以确定我们操作一个对象的行为,比如说获取一个值或者设定一个值
简单的来说,代理模式就不是直接对一个人说话了,而是另外又找了一个人做传话的。在Javascript中,我们不与对象直接交互,而是通过Proxy对象与目标的对象交互。
如何使用
怎么写呢,这边举个例子
const person = {
name: "max",
age: 21,
};
const personProxy = new Proxy(person, {
get(obj, prop) {
console.log(obj[prop]);
return obj[prop];
},
set(obj, prop, value) {
obj[prop] = value;
console.log(obj[prop]);
},
});
personProxy.name;
personProxy.age = 22;
在上面的例子中,我们使用person对象创建了一个personProxy对象,通过这个Proxy对象我们可以对person对象进行一些操作。
当我们操作name属性,Proxy对象执行了里面get方法,而当我们尝试修改age属性里面值的时候,执行了set方法。
那么Proxy模式适合用在什么地方呢?有时候当我们获取一个对象值或者修改一个对象值的时候,可能还需要做一些额外的副作用操作,比如说校验获取或者传入的值,打log之类的。而且使用Proxy对象来操作目标对象能保证对象的数据不会被污染。
更多方法
Reflect
在编写proxy中的get和set方法时候,除了直接操作原来的对象,我们还可以使用reflect来操作,正如它的名字,它是一个反射,能把操作反射在自己身上。但是实际上和直接操作是没有什么区别的,相当于一个,emmm,快捷方式?如果对一些数据操作有特别需求的可以尝试用一下,但是一般get和set感觉没什么区别。
const person = {
name: "max",
age: 21,
};
const personProxy = new Proxy(person, {
get(obj, prop) {
console.log(Reflect.get(obj, prop));
return Reflect.get(obj, prop);
},
set(obj, prop, value) {
Reflect.set(obj, prop, value);
console.log(Reflect.get(obj, prop));
},
});
personProxy.name;
personProxy.age = 22;
注意看get 和set 的部分,可以看到Reflect其实和基本的直接操作是没什么区别的,但是除了这些基本用法以外,Reflect还有其它的一些方法,如表
Reflect方法 | 类似于 |
---|---|
Reflect.apply(target, thisArgument, argumentsList) | Function.prototype.apply() |
Reflect.construct(target, argumentsList[, newTarget]) | new target(…args) |
Reflect.defineProperty(target, prop, attributes) | Object.defineProperty() |
Reflect.deleteProperty(target, prop) | delete target[name] |
Reflect.get(target, prop[, receiver]) | target[name] |
Reflect.getOwnPropertyDescriptor(target, prop) | Object.getOwnPropertyDescriptor() |
Reflect.getPrototypeOf(target) | Object.getPrototypeOf() |
Reflect.has(target, prop) | in 运算符 |
Reflect.isExtensible(target) | Object.isExtensible() |
Reflect.ownKeys(target) | Object.keys() |
Reflect.preventExtensions(target) | Object.preventExtensions() |
Reflect.set(target, prop, value[, receiver]) | target[prop] = value |
Reflect.setPrototypeOf(target, prototype) | Object.setPrototypeOf() |