// 代理模式的一些有用编程方式
1:跟踪属性访问
const user = {
name: 'jack'
};
const proxy = new Proxy(user, {
get(target, property, receiver) {
console.log(`getting ${property}`);
return Reflect.get(...arguments)
},
set(target, property, value, receiver) {
console.log(`setting ${property}=${value}`);
return Reflect.set(...arguments)
}
});
proxy.name;//getting name
proxy.age = 25;//setting age=25
2:隐藏属性,代理的内部实现对外部代码是不可见得,因此要隐藏目标对象上的属性也是轻而易举的
const hiddenProperties = ['foo', 'bar'];
const targetObj = {
foo: 1,
bar: 2,
baz: 3
}
const proxy = new Proxy(targetObj, {
get(target, property) {
if (hiddenProperties.includes(property)) {
return undefined
}
else {
return Reflect.get(...arguments)
}
},
has(target, property) {
if (hiddenProperties.includes(property)) {
return false
}
else {
return Reflect.has(...arguments)
}
}
})
console.log(proxy.foo);//undefined
console.log(proxy.bar);//undefined
console.log(proxy.baz);//3
console.log('foo' in proxy);//false
console.log('bar' in proxy);//false
console.log('baz' in proxy);//true
3:属性验证
const target = {
onlyNumbersGoHere: 0
};
const proxy = new Proxy(target, {
set(target, property, value) {
if (typeof value !== 'number') {
return false
}
else {
return Reflect.set(...arguments)
}
}
})
proxy.onlyNumbersGoHere = 1;
console.log(proxy.onlyNumbersGoHere);//1
proxy.onlyNumbersGoHere = '2';
console.log(proxy.onlyNumbersGoHere);//1
4:函数和构造函数参数验证
const median = function (...nums) {
return nums.sort()[Math.floor(nums.length / 2)]
}
const proxy = new Proxy(median, {
apply(target, thisArg, argumentsList) {
for (const arg of argumentsList) {
if (typeof arg !== 'number') {
throw 'Non-number argument provided'
}
}
return Reflect.apply(...arguments)
}
})
console.log(proxy(1, 3, 6));//3
console.log(proxy(1, '3', 6));//Non-number argument provided
5:使用事件分派程序,每次插入新实例都会发送信息
const userList = [];
function emit(newValue) {
console.log(newValue)
}
const proxy = new Proxy(userList, {
set(target, property, value, receiver) {
const result = Reflect.set(...arguments);
if (result) {
emit(Reflect.get(target, property, receiver))
}
return result
}
});
proxy.push("john");//john //1 使用数组方法改变元素后,会把当前length传进去触发set
proxy[1] = 'tom';//tom