代理可捕获13种不同的基本操作。
这些操作有各自不同的反射API方法、参数、关联ECMAScript操作和不变式。
正如前面示例所展示的,有几种不同的JavaScript操作会调用同一个捕获器处理程序。
不过,对于在代理对象上执行的任何一种操作,只会有一个捕获处理程序被调用。不会存在重复捕获的情况。
只要在代理上调用,所有捕获器都会拦截它们对应的反射API操作。
9.2.1 get()
get()捕获器会在获取属性值的操作中被调用。对应的反射API方法为Reflect.get()。
const myTarget = {};const proxy = new Proxy(myTarget, {get(target, property, receiver) {console.log('get()');return Reflect.get(...arguments);}});proxy.foo;// get()
9.2.2 set()
set()捕获器会在设置属性值的操作中被调用。对应的反射API方法为Reflect.set()。
const myTarget = {};const proxy = new Proxy(myTarget, {set(target, property, value, receiver) {console.log('set()');return Reflect.set(...arguments);}});proxy.foo = 'bar';// get()
9.2.3 has()
has()捕获器会在in操作符中被调用。对应的反射API方法为Reflect.has()。
const myTarget = {};const proxy = new Proxy(myTarget, {has(target, property) {console.log('has()');return Reflect.has(...arguments);}});'foo' in proxy;// has()
9.2.4 defineProperty()
defineProperty()捕获器会在Object.defineProperty()中被调用。对应的反射API方法为Reflect.defineProperty()。
const myTarget = {};const proxy = new Proxy(myTarget, {defineProperty(target, property,descriptor) {console.log('defineProperty()');return Reflect.defineProperty(...arguments);}});Object.defineProperty(proxy, 'foo', {vakue: 'bar'});// defineProperty
9.2.5 getOwnPropertyDescriptor()
getOwnPropertyDescriptor()捕获器会在Object.getOwnPropertyDescriptor()中被调用。对应的反射API方法为Reflect.getOwnPropertyDescriptor()。
const myTarget = {};const proxy = new Proxy(myTarget, {getOwnPropertyDescriptor(target, property) {console.log('getOwnPropertyDescriptor()');return Reflect.getOwnPropertyDescriptor(...arguments);}});Object.getOwnPropertyDescriptor(proxy, 'foo');// defineProperty
9.2.6 deleteProperty()
deleteProperty()捕获器会在delete操作符中被调用。对应的反射API方法为Reflect.deleteProperty()。
const myTarget = {};const proxy = new Proxy(myTarget, {deleteProperty(target, property) {console.log('deleteProperty()');return Reflect.deleteProperty(...arguments);}});delete poperty.foo// deleteProperty
9.2.7 ownKeys()
ownKeys()捕获器会在Object.keys()及类似方法中被调用。对应的反射API方法为Reflect.ownKeys()。
const myTarget = {};const proxy = new Proxy(myTarget, {ownKeys(target) {console.log('ownKeys()');return Reflect.ownKeys(...arguments);}});Object.keys(proxy);// ownKeys()
9.2.8 getPrototypeOf()
getPrototypeOf()捕获器会在Object.getPrototypeOf()中被调用。对应的反射API方法为Reflect.getPrototypeOf()。
const myTarget = {};const proxy = new Proxy(myTarget, {getPrototypeOf(target) {console.log('getPrototypeOf()');return Reflect.getPrototypeOf(...arguments);}});Object.getPrototypeOf(proxy);// getPrototypeOf()
9.2.9 setPrototypeOf()
setPrototypeOf()捕获器会在Object.setPrototypeOf()中被调用。对应的反射API方法为Reflect.setPrototypeOf()。
const myTarget = {};const proxy = new Proxy(myTarget, {setPrototypeOf(target, prototype) {console.log('setPrototypeOf()');return Reflect.setPrototypeOf(...arguments);}});Object.setPrototypeOf(proxy, Object);// setPrototypeOf()
9.2.10 isExtensible()
isExtensible()捕获器会在Object.isExtensible()中被调用。对应的反射API方法为Reflect.isExtensible()。
const myTarget = {};const proxy = new Proxy(myTarget, {isExtensible(target) {console.log('isExtensible()');return Reflect.isExtensible(...arguments);}});Object.isExtensible(proxy);// isExtensible()
9.2.11 preventExtensions()
preventExtensions()捕获器会在Object.preventExtensions()中被调用。对应的反射API方法为Reflect.preventExtensions()。
const myTarget = {};const proxy = new Proxy(myTarget, {preventExtensions(target) {console.log('preventExtensions()');return Reflect.preventExtensions(...arguments);}});Object.preventExtensions(proxy);// preventExtensions()
9.2.12 apply()
apply()捕获器会在调用函数时中被调用。对应的反射API方法为Reflect.apply()。
const myTarget = () => {};const proxy = new Proxy(myTarget, {apply(target, thisArg, ...argumentsList) {console.log('apply()');return Reflect.apply(...arguments);}});proxy();// apply()
9.2.13 construct()
construct()捕获器会在new操作符中被调用。对应的反射API方法为Reflect.construct()。
const myTarget = function() {};const proxy = new Proxy(myTarget, {construct(target, argumentsList, newTarget) {console.log('construct()');return Reflect.construct(...arguments)}});new proxy;// construct()
