参考文档:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy
一、Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。
语法
const p = new Proxy(target, handler)
target
要使用proxy包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
handler
一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理p 的行为。
常用方法
handler和reflect的方法是一一对应的,总共13种
handler.getPrototypeOf()
Object.getPrototypeOf 方法的捕捉器。
handler.setPrototypeOf()
Object.setPrototypeOf 方法的捕捉器。
handler.isExtensible()
Object.isExtensible 方法的捕捉器。
handler.preventExtensions()
Object.preventExtensions 方法的捕捉器。
handler.getOwnPropertyDescriptor()
Object.getOwnPropertyDescriptor 方法的捕捉器。
handler.defineProperty()
Object.defineProperty 方法的捕捉器。
handler.has()
in 操作符的捕捉器。
handler.get()
属性读取操作的捕捉器。
handler.set()
属性设置操作的捕捉器。
handler.deleteProperty()
delete 操作符的捕捉器。
handler.ownKeys()
Object.getOwnPropertyNames 方法和 Object.getOwnPropertySymbols 方法的捕捉器。
handler.apply()
函数调用操作的捕捉器。
handler.construct()
new 操作符的捕捉器。
二、部分方法示例
get和set拦截示例
let target = {};
const hander1 ={
set:function (target,key,value){
if(key=="name"||key=="age"){
Reflect.set(...arguments);
}
else{
console.log("SET : parm's name is not valid");
}
},
get:function(target , key){
if(key=="name"||key=="age"){
return Reflect.get(...arguments);
}
else{
console.log("GET : parm's name is not valid");
}
},
}
let proxy = new Proxy(target,hander1);
proxy.address = "中国";
proxy.name = "张三";
proxy.age = 19;
console.log(proxy.address);
console.log(proxy.name);
console.log(proxy.age);
apply拦截示例
function sum(a, b) {
return a + b;
}
const handler = {
apply: function(target, thisArg, argumentsList) {
return target(argumentsList[0], argumentsList[1]) * 10;
}
};
const proxy1 = new Proxy(sum, handler);
console.log(sum(1, 5));
console.log(sum.call(proxy1,1,5));
console.log(proxy1(1,5))
console.log(proxy1.apply(sum,[1,5]))
console.log(proxy1.call(sum,1,5))
console.log(proxy1.bind(sum)(1,5))
output:
6
6
60
60
60
60
下面四个方法都被拦截了
proxy1(1,5))
proxy1.apply(sum,[1,5])
proxy1.call(sum,1,5)
proxy1.bind(sum)(1,5)
getPrototypeOf
const monster1 = {
eyeCount: 4
};
const monsterPrototype = {
eyeCount: 2
};
const handler = {
getPrototypeOf(target) {
return monsterPrototype;
}
};
const proxy1 = new Proxy(monster1, handler);
console.log(Object.getPrototypeOf(proxy1) === monsterPrototype);
// expected output: true
console.log(Object.getPrototypeOf(proxy1).eyeCount);
// expected output: 2