JS。 代理人。 要知道的陷阱

对于使用Proxy进行反应或反思的用户,本文会很感兴趣。
如果我们仅在对象中使用JS方法,那么它的行为就为我们所熟知。
如果将方法通过属性传递给另一个对象,则该方法与在另一个对象的框架中定义的方法一起使用。

let obj1={prop1:'HEllo',method1(){console.log(this);}} let obj2={method2:obj1.method1}; obj2.method2(); 

使用代理时必须清楚了解这一点。

 class MyProxy{ constructor(target){ return new Proxy(target,this); } get(target,prop){ console.log(target,prop); //Label1 return target[prop]; } } class PrimitiveType { constructor(target,prop) { this.target=target; this.prop=prop; } get(){ console.log(this);// Label2 return this.target[this.prop]; } } prim=new PrimitiveType({a:''},'a'); proxy= new MyProxy(prim); proxy.get(); 

结果是console.log(Label2); 将为我们提供一个Proxy对象,之后Proxy将同时在target和prop上工作(请参见Label1); 但是代码似乎可以正常工作。 洗澡什么。

该方法开始通过代理与对象(this)进行通信。 当我们编写反射(对象的属性的反射和行为的变化而不更改对象)时,这是方便且合乎逻辑的。 但是,如果我们不需要它,而我们需要该方法专门用于目标对象,那该怎么办? 为什么我们放慢代码的速度?

此外,如果我们引入更多逻辑,例如属性过滤器等,则代码可能会意外弯曲。 并且在编写反应式代码时,存在“过渡”。 (例如,当请求一个方法及其后续执行时,该方法通过已发布事件的代理请求属性)。 就是说,事件在不需要和预期不到的地方开始发生。

如何修复


可以理解,在Proxy中调用Handler.get之前,该方法已被覆盖。 您只需要再次重新定义它,如下所示:

 let answer=target[prop]; if(typeof target[prop] ==='function'){ answer=target[prop].bind(target); } 

我们得到以下代码:

 class MyProxy{ constructor(target){ return new Proxy(target,this); } get(target,prop){ //     valueOf.       get let answer=target[prop]; if(typeof target[prop] ==='function'){ answer=target[prop].bind(target); } return answer; } } class PrimitiveType { constructor(target,prop) { this.target=target; this.prop=prop; } get(){ console.log(this); return this.target[this.prop]; } } prim=new PrimitiveType({a:''},'a'); proxy= new MyProxy(prim); proxy.get(); 

最后,作为奖励。


创建反应/反射链。 每个嵌套对象将是一个代理:

 class MyProxy{ constructor(target){ return new Proxy(target,this); } get(target,prop){ let answer; let tp=target[prop];//    target - Proxy  target[prop] -getter if(typeof tp==='object' && tp!==null){ answer =new MyProxy(tp); } else if(typeof tp ==='function'){ //   .       answer=tp.bind(target); } else { answer=tp; } return answer; } } class PrimitiveType { constructor(target,prop) { this.target=target; this.prop=prop; } valueOf(){ console.log(this); return this.target[this.prop]; } } prim=new PrimitiveType({a:''},'a'); qwer={q:prim}; proxy= new MyProxy(qwer); proxy.q 

感谢您的关注!

Source: https://habr.com/ru/post/zh-CN454292/


All Articles