这里写目录标题
- getPrototypeOf(target) 捕捉器
- setPrototypeOf(target, prototype) 捕捉器
- isExtensible(target) 捕捉器
- preventExtensions(target) 捕捉器
- getOwnPropertyDescriptor(target, prop) 捕捉器
- defineProperty(target, prop, descriptor) 捕捉器
- has(target, prop) 捕捉器
- get(target, prop, receiver) 捕捉器
- set(target, prop, value, receiver) 捕捉器
- deleteProperty(target, prop) 捕捉器
- ownKeys(target) 捕捉器
- getOwnPropertyNames(target) 捕捉器
- getOwnProperty
- apply捕捉器
- constructor捕捉器
getPrototypeOf(target) 捕捉器
参数:target - 被代理的目标对象
返回值:代理后的目标对象的原型对象
作用:拦截对代理对象原型的获取操作
使用方法:
const person = { name: '小明' };
const proxyPerson = new Proxy(person, {
getPrototypeOf(target) {
console.log('拦截到获取原型的操作');
return Object.getPrototypeOf(target);
}
});
console.log(Object.getPrototypeOf(proxyPerson)); // 输出: "拦截到获取原型的操作" 和 "Object {}"(person对象的原型对象)
setPrototypeOf(target, prototype) 捕捉器
参数:target - 被代理的目标对象,prototype - 新的原型对象
返回值:是否设置成功
作用:拦截对代理对象原型的设置操作
使用方法:
const person = { name: '小明' };
const proxyPerson = new Proxy(person, {
setPrototypeOf(target, prototype) {
console.log('拦截到设置原型的操作');
return Reflect.setPrototypeOf(target, prototype);
}
});
console.log(Object.setPrototypeOf(proxyPerson, {})); // 输出: "拦截到设置原型的操作" 和 "true"
isExtensible(target) 捕捉器
参数:target - 被代理的目标对象
返回值:目标对象是否可扩展
作用:拦截对代理对象可扩展性的获取操作
使用方法:
const person = { name: '小明' };
const proxyPerson = new Proxy(person, {
isExtensible(target) {
console.log('拦截到获取可扩展性的操作');
return Reflect.isExtensible(target);
}
});
Object.preventExtensions(proxyPerson); // 使得proxyPerson不可扩展
console.log(Object.isExtensible(proxyPerson)); // 输出: "拦截到获取可扩展性的操作" 和 "false"
preventExtensions(target) 捕捉器
参数:target - 被代理的目标对象
返回值:是否设置成功
作用:拦截对代理对象可扩展性的设置操作
使用方法:
const person = { name: '小明' };
const proxyPerson = new Proxy(person, {
preventExtensions(target) {
console.log('拦截到不可扩展的设置操作');
return Reflect.preventExtensions(target);
}
});
console.log(Object.preventExtensions(proxyPerson)); // 输出: "拦截到不可扩展的设置操作" 和 "person {}"
getOwnPropertyDescriptor(target, prop) 捕捉器
参数:target - 被代理的目标对象,prop - 要获取的属性名
返回值:目标对象中属性的描述符对象
作用:拦截对代理对象属性描述符的获取操作
使用方法:
const person = { name: '小明' };
const proxyPerson = new Proxy(person, {
getOwnPropertyDescriptor(target, prop) {
console.log('拦截到获取属性描述符的操作');
return Object.getOwnPropertyDescriptor(target, prop);
}
});
console.log(Object.getOwnPropertyDescriptor(proxyPerson, 'name')); // 输出: "拦截到获取属性描述符的操作" 和 "{value: "小明", writable: true, enumerable: true, configurable: true}"(name属性的描述符对象)
defineProperty(target, prop, descriptor) 捕捉器
参数:target - 被代理的目标对象,prop - 要定义的属性名,descriptor - 新属性的描述符对象
返回值:是否设置成功
作用:拦截对代理对象属性描述符的设置操作
使用方法:
const person = { name: '小明' };
const proxyPerson = new Proxy(person, {
defineProperty(target, prop, descriptor) {
console.log('拦截到设置属性描述符的操作');
return Reflect.defineProperty(target, prop, descriptor);
}
});
Object.defineProperty(proxyPerson, 'age', { value: 18, writable: true, enumerable: true, configurable: true }); // 给proxyPerson对象新增一个age属性
console.log(proxyPerson.age); // 输出: "18"
has(target, prop) 捕捉器
参数:target - 被代理的目标对象,prop - 要检查的属性名
返回值:布尔值,表示属性是否存在
作用:拦截对代理对象属性是否存在的查找操作
使用方法:
const person = { name: '小明' };
const proxyPerson = new Proxy(person, {
has(target, prop) {
console.log('拦截到查找属性是否存在的操作');
return Reflect.has(target, prop);
}
});
console.log('name' in proxyPerson); // 输出: "拦截到查找属性是否存在的
操作" 和 “true”
get(target, prop, receiver) 捕捉器
参数:target - 被代理的目标对象,prop - 要获取的属性名,receiver - 如果获取的是函数,receiver就是this对象
返回值:目标对象中对应属性值
作用:拦截对代理对象属性值的获取操作
使用方法:
const person = { name: '小明' };
const proxyPerson = new Proxy(person, {
get(target, prop, receiver) {
console.log('拦截到获取属性值的操作');
return Reflect.get(target, prop, receiver);
}
});
console.log(proxyPerson.name); // 输出:"拦截到获取属性值的操作" 和 "小明"
set(target, prop, value, receiver) 捕捉器
参数:target - 被代理的目标对象,prop - 要设置的属性名,value - 属性的新值,receiver - 如果设置的是函数,receiver就是this对象
返回值:是否设置成功
作用:拦截对代理对象属性值的设置操作
使用方法:
const person = { name: '小明' };
const proxyPerson = new Proxy(person, {
set(target, prop, value, receiver) {
console.log('拦截到设置属性的操作');
return Reflect.set(target, prop, value, receiver);
}
});
proxyPerson.age = 18; // 给proxyPerson对象新增一个age属性
console.log(proxyPerson.age); // 输出: "拦截到设置属性的操作" 和 "18"
deleteProperty(target, prop) 捕捉器
参数:target - 被代理的目标对象,prop - 要删除的属性名
返回值:是否删除成功
作用:拦截对代理对象属性的删除操作
使用方法:
const person = { name: '小明' };
const proxyPerson = new Proxy(person, {
deleteProperty(target, prop) {
console.log('拦截到删除属性的操作');
return Reflect.deleteProperty(target, prop);
}
});
delete proxyPerson.name; // 删除proxyPerson对象的name属性
console.log(proxyPerson.name); // 输出: "undefined"
ownKeys(target) 捕捉器
参数:target - 被代理的目标对象
返回值:目标对象自身可枚举属性名数组
作用:拦截对代理对象自身属性名的获取操作,包括Symbol类型
使用方法:
const person = { name: '小明' };
const proxyPerson = new Proxy(person, {
ownKeys(target) {
console.log('拦截到获取属性名的操作');
return Reflect.ownKeys(target);
}
});
console.log(Object.keys(proxyPerson)); // 输出:"拦截到获取属性名的操作" 和 "[name]"(自身可枚举属性名数组)
getOwnPropertyNames(target) 捕捉器
参数:target - 被代理的目标对象
返回值:目标对象自身属性名数组,不包括Symbol类型属性
作用:拦截对代理对象自身非Symbol类型属性名的获取操作
使用方法:
const person = { name: '小明' };
const proxyPerson = new Proxy(person, {
getOwnPropertyNames(target) {
console.log('拦截到获取属性名的操作');
return Reflect.getOwnPropertyNames(target);
}
});
console.log(Object.getOwnPropertyNames(proxyPerson)); // 输出:"拦截到获取属性名的操作" 和 "[name]"(自身属性名数组)
getOwnProperty
参数 :getOwnProperty 捕捉器有两个参数,target 和 prop。
target:目标对象。
prop:通过 Reflect.ownKeys 获取到的属性字符串或者符号。
返回值:一个值,代表属性描述符,可以是对象或 undefined。
作用:getOwnProperty 捕捉器用于拦截对对象属性描述符的获取。
使用方法
下面是一个简短的例子,我们使用 getOwnPropertyDescriptor 和 set 和 getOwnPropertyDescriptor 捕捉器来实现只读属性。
const obj = { name: '小花' };
const readonlyObj = new Proxy(obj, {
getOwnPropertyDescriptor(target, prop) {
const descriptor = Object.getOwnPropertyDescriptor(target, prop);
if (descriptor) {
descriptor.writable = false;
}
return descriptor;
},
set(target, prop) {
console.error(`"${prop}" 属性是只读的。`);
return true;
}
});
// 只读属性
readonlyObj.name = '小鹿';
// logs: "\"name\" 属性是只读的。"
// 可写属性
obj.name = '小狗';
console.log(obj.name);
// output: "小狗"
在这个例子中,我们拦截了 getOwnPropertyDescriptor 方法,可以设置为只读属性。如果尝试设置只读属性,则会抛出一个错误。
apply捕捉器
参数
apply 捕捉器有三个参数:target、thisArg 和 argumentsList。
target:目标函数。
thisArg:被调用时的上下文对象(即this关键字)。
argumentsList:一个可用于函数调用的参数数组。
返回值
apply 捕捉器返回目标函数调用的结果。
作用
apply 捕捉器用于拦截函数调用,并返回调用结果。
使用方法
下面是一个简单的例子,我们在函数调用时,拦截并输出函数名称和参数。
const handler = {
apply(target, thisArg, argumentsList) {
console.log(`Calling ${target.name} with arguments:`, argumentsList);
return target.apply(thisArg, argumentsList);
}
};
function sayHello(message) {
console.log(`Hello, ${message}!`);
}
const sayHelloProxy = new Proxy(sayHello, handler);
sayHelloProxy('world');
在上面的例子中,我们通过 new Proxy 创建了一个代理对象 sayHelloProxy,并设置了 apply 捕捉器。当我们调用 sayHelloProxy 函数时,捕捉器会首先被触发,输出函数名称和参数,并执行目标函数,并将目标函数执行的结果返回。
输出如下所示:
Calling sayHello with arguments: ["world"]
Hello, world!
constructor捕捉器
参数
constructor 捕捉器有两个参数:target 和 argumentsList。
target:目标构造函数。
argumentsList:一个可用于构造函数调用的参数数组。
返回值
constructor 捕捉器需要返回一个对象,该对象会被当做代理对象的返回值。
作用
constructor 捕捉器用于拦截构造函数的调用,并返回代理对象。
使用方法
下面是一个简单的例子,我们通过 new Proxy 创建一个代理对象,代理一个构造函数,然后拦截构造函数的调用,输出构造函数名称和参数,并返回代理对象。
const handler = {
construct(target, argumentsList) {
console.log(`Constructing ${target.name} with arguments:`, argumentsList);
return new target(...argumentsList);
}
};
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
const PersonProxy = new Proxy(Person, handler);
const person = new PersonProxy('Tom', 18);
console.log(person);
在上面的例子中,我们通过 new Proxy 创建了一个代理对象 PersonProxy,并设置了 constructor 捕捉器。当我们通过 new PersonProxy 创建实例时,捕捉器会首先被触发,输出构造函数名称和参数,并执行目标构造函数,并将结果返回作为代理对象。
输出如下所示:
Constructing Person with arguments: ["Tom", 18]
Person { name: 'Tom', age: 18 }