Proxy(代理)特性与Reflect

Proxy(代理)特性:
代理一个对象,可以在代理对象上注册处理函数(trap),代理上执行操作的时候会调用处理函数。
这些处理函数除了把操作转发给原始目标 / 被代理对象之外,还可以执行其他逻辑。
var obj = {a:1,b:2};
var handler = {
  get(target,key,context){
    console.log(target);//被代理的对象,此处为obj
    console.log(key);
    console.log(context);//代理后的对象,此处为proxyObj
    return Reflect.get(target,key,context);
  }
}
var proxyObj = new Proxy(obj,handler);
proxyObj.a;
//执行结果
//{ a: 1, b: 2 }
//a
//{ a: 1, b: 2 }

1.此处定义了一个handler对象,用作Proxy的第二个参数,通常以函数作为属性,各属性中的函数分别定义了在执行操作时,代理对象的行为。
此处定义了一个trap处理函数get,get大家都不陌生,当要访问对象属性的时候,会调用[[Get]],此处的处理函数则会拦截[[Get]]运算;
它接受一个 target 对象的引用(obj)、key 属性名,以及接收者 /代理对象自身(proxyObj)。

2.我们把对 obj 的操作通过 Reflect.get(..)进行“转发”。
Reflect对象是一个平凡对象(就像 Math),不是函数且不可构造,Reflect的所有属性和方法都是静态的。
每个可用的代理处理函数 trap 都有一个对应的同名Reflect 函数。
也就是Proxy有的,Reflect就有,至于处理函数的名字大多都与Object所拥有的函数相同。
每个proxy处理函数在对应的任务执行的时候进行拦截,而每个 Reflect 工具在一个对象上执行相应的任务。
别问,问就是Proxy 和 Reflect 总是这么协同工作的。

3.可取消的代理
{ proxy: pobj, revoke: prevoke } = Proxy.revocable( obj, handlers );
revocable方法返回一个结构为{"proxy": proxy, "revoke": revoke}的对象;
此处解构赋值一下,pobj即为代理对象自身,调用prevoke()即可取消代理。

4.为什么要用Proxy和Reflect?
Proxy的目的在于修改某些方法的默认行为;以往set就是设置值,get就是获取值,现在通过代理处理函数拦截操作后可得到更加丰富的结果。
Reflect映射一些明显属于对象语言内部的方法;Reflect在属性定义成功或失败时返回Boolean值,在做判断时方便许多;
Reflect让Object操作都变成函数行为,比如 name in obj 和 delete obj[name],变为了Reflect.has(obj, name) 和 Reflect.deleteProperty(obj, name)。

posted @ 2021-04-09 14:59  你风致  阅读(332)  评论(0编辑  收藏  举报