javascript 使用代理记录getter获取的内容

watbbzwu  于 2023-06-04  发布在  Java
关注(0)|答案(2)|浏览(117)

我有下面的代理处理程序来记录get事件。

const proxyHandler = {
  get: function(target, prop) {
    console.log("get", prop);
    return Reflect.get(target, prop);
  }
};

const obj = new Proxy(
  {
    value: 4,
    text: "hi",
    get textVal() {
      return this.text.repeat(this.value);
    },
    getTextVal() {
      return this.text.repeat(this.value);
    }
  },
  proxyHandler
);


console.log("------- normal func -------")
console.log(obj.getTextVal());
console.log("------- getter func -------")
console.log(obj.textVal);

当我记录console.log(obj.getTextVal())时,我得到:

get getTextVal 
get text 
get value 
hihihihi

但是当我记录getter console.log(obj.textVal)时,我只得到以下内容:

get textVal 
hihihihi

如何让obj.textVal记录get text并使用代理获取get value事件?当运行console.log(obj.textVal)时,我希望得到以下结果。

get getTextVal 
get text 
get value 
hihihihi
ru9i0ody

ru9i0ody1#

上面的答案是可行的,但还有一个更优雅的解决方案。您在代理陷阱和反射参数中缺少receiver。只需将代理更改为:

const proxyHandler = {
  get: function(target, prop, receiver) {
    console.log("get", prop);
    return Reflect.get(target, prop, receiver);
  }
};

注意trap和Reflect参数中的新receiver
代理陷阱targetreceiver之间有一个重要的区别。在本例中,target是底层原始对象,而receiver是代理 Package 器。如果你没有将receiver传递给Reflect调用,get操作中的所有内容都将针对原始对象运行,并且不会触发代理陷阱。
如果你有时间,我建议你阅读ES6规范的相关部分,以充分掌握这两者之间的区别。否则,只要确保将allProxy trap参数转发到匹配的Reflect调用(如果您的目标是透明 Package )。

mctunoxg

mctunoxg2#

您可以将Proxy示例设置为proxyHandler对象,并通过它访问属性(而不是this)。

const proxyHandler = {
  get: function(target, prop) {
    console.log("get", prop);
    return Reflect.get(target, prop);
  }
};
const proxifiedObj = {
    value: 4,
    text: "hi",
    get textVal() {
      return this.proxyInstance.text.repeat(this.proxyInstance.value);
    },
    getTextVal() {
      return this.text.repeat(this.value);
    }
}

obj = proxifiedObj.proxyInstance = new Proxy(proxifiedObj, proxyHandler);



console.log("------- normal func -------")
console.log(obj.getTextVal());
console.log("------- getter func -------")
console.log(obj.textVal);
console.log(obj.textVal);
get getTextVal 
get text 
get value 
hihihihi

更新:

或者,您也可以创建一个自定义的Proxy来完成同样的工作,该Proxy为您执行赋值操作
(Note:Proxy类不能被扩展,但我们可以使用constructor return value模式):

class InstanceAwareProxy {
      constructor(proxifiedObject, proxyHandler) {
          return proxifiedObject.proxyInstance 
                 = new Proxy(proxifiedObject, proxyHandler);
      }
  }

  obj = new InstanceAwareProxy(proxifiedObj, proxyHandler);

相关问题