博客
zyzcio.gitee.io
第九章:代理与反射
ES6中新增的代理与反射:提供了拦截
并向基本操作嵌入额外行为
的能力;具体的实现方式就是:通过一个给目标对象
定义一个关联的代理对象
,通过代理对象
内部的操作对目标对象
的操作加以控制
注意:代理和反射只在百分百支持它们的平台上有用
9.1 代理基础
从很多方面看,代理
类似C++的指针
,可以用作对象的替身;当然,目标对象既可以直接操作(会绕过代理)、也可以通过代理来操作。
9.1.1 代理创建
通过Proxy
构造函数创建,其接收两个参数:
- 目标对象
- 处理程序对象
两个参数是必需
的;缺一个就会报错。
// 创建目标对象
const targetObject = {
name:'target'
}
// 创建空处理程序对象
const handler = { /* 对数据进行一些操作(捕获器) */};
const proxy = new Proxy(targetObject,handler);
// 给目标对象赋值 会反映在两个对象上
targetObject.name = 'hello';
console.log(targetObject.name); //hello
console.log(proxy.name); //hello
// 給代理对象赋值 也会反映在两个对象上
proxy.name = 'world';
console.log(targetObject.name); //world
console.log(proxy.name); //world
9.1.2 定义捕获器
使用代理的主要目的是定义捕获器
;
- 捕获器:处理程序对象中定义的“基本操作的拦截器”;
- 每个程序可以包括
0个或多个
; - 每个捕获器对应一种
基本操作
,可以直接
或间接
在代理对象上调用;
每次在代理对象
上调用这些基本操作
的时候,代理
可以在这些操作传播到目标对象之前先调用捕获器函数,从而拦截并修改相应的行为。
const targetObject = {
name:'target'
}
const handler = {
get() {
return "hello world!"
}
};
const proxy = new Proxy(targetObject,handler);
console.log(targetObject.name); // target
console.log(proxy.name); // hello world!
显然,直接操作对象,会绕过代理器
9.1.3 捕获器参数 结合 反射API
所有捕获器都可以访问相应的参数
,可以基于这些参数
重建被捕获方法的原始行为。一般参数如下:
- trapTarget:被捕获的目标对象
- property:属性
- value:值
- receiver:代理程序对象
const targetObject = {
name:'target'
}
const handler = {
get(trapTarget,property,receiver) {
console.log(trapTarget); // { name:'target' }
console.log(property); // name
console.log(receiver); // { name:'target' }
return targetObject[name]; // 如