proxy代理,就是在目标对象的前面设置一个拦截层,外界在访问这个对象的时候,必须经过拦截层。 我们可以在拦截层做一些过滤或者是改写的操作。
const proxy = new Proxy({}, {
get: () => {
console.log("get");
},
set: () => {
console.log("set")
}
})
proxy.count = 1; // set
++proxy.count; // get
Proxy接受两个参数,第一个参数是拦截目标对象;第二个参数是设置拦截的操作,所谓的拦截,一般都是有一些操作行为的,如果在拦截层没有设置任何操作的话,就会直接访问目标对象。
Proxy支持的拦截操作
get(target,Prophet,receiver)
拦截对象的读取属性操作。
const proxy = new Proxy({ name: "duXin", count: 90 }, {
get: () => {
console.log("get");
return 100
},
})
console.log(proxy.name)
在访问目标对象的时候,无论是name属性还是count属性,都会返回100,因为在拦截层设置读取属性时都返回100。
set()
方法是设置属性值操作的捕获器。
const proxy_set = new Proxy({}, {
set: function (target, prop, value, receiver) {
target[prop] = value;
console.log('property set: ' + prop + ' = ' + value);
return true;
}
})
console.log("======proxy_set=======")
console.log('name' in proxy_set); // false
proxy_set.name = 'duXin'; // property set: name = duXin
console.log('name' in proxy_set); // true
has()
对in操作符的代理方法。
const targetObj = {
_secret: 'easily scared',
eyeCount: 4
};
const proxy_has = new Proxy(targetObj, {
has: (target, key) => {
console.log("key==",key)
if (key.includes('_')) {
return false;
}
return key in target;
}
})
console.log('eyeCount' in targetObj); // true
console.log('_secret' in proxy_has); // false
construct()
拦截new操作符,返回的是一个对象。
function proxy_construct_obj(disposition){
this.disposition = disposition;
}
const proxyConstruct = new Proxy(proxy_construct_obj, {
construct: function (target, args) {
return new target(...args);
}
})
console.log(new proxyConstruct("duXinYue").disposition)
apply()
拦截函数的调用。 语法:
var p = new Proxy(target, {
apply: function(target, thisArg, argumentsList) {
}
});
target:目标对象,也就是函数 thisArg:被调用时的上下文对象 argumentsList:被调用时的参数,是一个类数组。
声明一个函数:
function sum(a, b) {
return a + b;
}
const proxy_apply = new Proxy(sum, {
apply: (target,thisArg, argumentsList) => {
console.log("target",target,thisArg, argumentsList)
return target(argumentsList[0], argumentsList[1]) * 10;
}
})
console.log(proxy_apply(1,2)); //30
defineProperty()
拦截对象的 Object.defineProperty() 操作符。
这是语法:
defineProperty: function(target, property, descriptor) {}
target:目标对象,
property:被检索的属性名
descriptor:待定义或者修改的属性的描述符
defineProperty的返回值必须是Boolean值,表示对该属性操作是否成功。
var desc = { configurable: true, enumerable: true, value: 10 };
var defineProperty = new Proxy(desc, {
defineProperty: function (target, prop, descriptor) {
console.log('called: ' + prop);
Reflect.defineProperty(target, prop, descriptor);
}
});
defineProperty.name = "908"
console.log("obj", defineProperty); // { configurable: true, enumerable: true, value: 10, name: '908' }