代理
空代理
从很多方面看,代理类似 C++指针,因为它可以用作目标对象的替身,但又完全独立于目标对象。目标对象既可以直接被操作,也可以通过代理来操作。但直接操作会绕过代理施予的行为。
Proxy 构造函数创建:接收两个参数:目标对象和处理程序对象
创建空代理,可以传一个简单的对象字面量作为处理程序对象
const target = {
id: 'target'
};
const handler = {};
const proxy = new Proxy(target, handler);
id 属性会访问同一个值
给目标属性赋值会反映在两个对象上/,因为两个对象访问的是同一个值
给代理属性赋值会反映在两个对象上,因为这个赋值会转移到目标对象
hasOwnProperty()方法在两个地方都会应用到目标对象
Proxy.prototype 是 undefined
// 因此不能使用 instanceof 操作符
严格相等可以用来区分代理和目标
console.log(target === proxy); // false·
定义捕获器
get() 捕获器
proxy[property] 、 proxy.property 或 Object.create(proxy)[property] 等操作都
会触发基本的 get() 操作以获取属性
const target = {
foo: 'bar'
};
const handler = {
// 捕获器在处理程序对象中以方法名为键
get() {
return 'handler override';
}
};
const proxy = new Proxy(target, handler);
console.log(target.foo); // bar
console.log(proxy.foo); // handler override
console.log(target['foo']); // bar
console.log(proxy['foo']); // handler override
get()捕获器会接收到目标对象、要查询的属性和代理对象三个参数:
const target = {
foo: 'bar',
boo: 'boo',
};
const handler = {
get(trapTarget, property, receiver) {
console.log(trapTarget === target);
console.log(property);
console.log(receiver === proxy);
}
};
const proxy = new Proxy(target, handler);
proxy.foo;
// true
// foo
// true
处理程序对象中所有可以捕获的方法都有对应的反射(Reflect)API 方法。这些方法与捕获器拦截
的方法具有相同的名称和函数签名,而且也具有与被拦截方法相同的行为。