Search code examples
javascriptes6-proxy

Log what getter gets using proxy


I have the following proxy handler that logs get events.

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);

When I log console.log(obj.getTextVal()) I get:

get getTextVal 
get text 
get value 
hihihihi 

But when I log the getter console.log(obj.textVal), I only get the following:

get textVal 
hihihihi 

How can I make obj.textVal log the get text and get get value events using proxy? ie. When running console.log(obj.textVal) I would like the following result.

get getTextVal 
get text 
get value 
hihihihi 

Solution

  • The above answer works but there is a bit more elegant solution. You are missing the receiver in your Proxy trap and Reflect arguments. Simply change the Proxy to this:

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

    Notice the new receiver in the trap and Reflect arguments.

    There is an important distinction between a Proxy trap target and receiver. In this case, the target is the underlying raw object while the receiver is the Proxy wrapper. If you do not pass the receiver to the Reflect call everything inside the get operation will be run against the raw object and won't trigger the Proxy traps.

    If you have the time I suggest you read the relevant parts of the ES6 spec to fully grasp the difference between these two. Otherwise, just make sure that you forward all Proxy trap args to the matching Reflect call if you are aiming for a transparent wrap.