0

I'm trying to make a proxy for a certain object to check if the properties are either accessed or modified then console.log the property that was changed. I'm fairly new to JavaScript so I'm not sure what could be causing the stack to overflow. I think it's due to a weird scope issue with console.log but I'm not sure. This is what my handler looks like

var handler = {
    set: function(obj, prop, value) {
         console.log(prop);
         obj[prop] = value;
    }
    get: function(obj, prop, receiver) {
          if (typeof prop !== 'symbol') console.log(prop);
          return obj[receiver];
    }
};

I'm assigning the handler to a CanvasRenderingContext2D element named ctx using this line.

 watchedCtx = new Proxy(ctx, handler);

I added the extra check to the get property method because I was receiving a lot of Symbol primitives from get method and I thought that was the issue so I attempted to filter them out. Has anyone else ever experience this issue or have any idea what may be causing this?

Akeem
  • 98
  • 1
  • 2
  • 10

1 Answers1

1

In your case, the typo is obj[receiver], which should be obj[prop]. receiver is an object (usually your proxy itself), so by doing obj[receiver], you're converting receiver into string, which requires calls to get, which then triggers the infinite recursion that you are seeing. That will resolve your issue, but as you might be wondering now, what's receiver for then?

In this case, receiver is critical for the correct operation of your proxy. The easiest way to deal with that if you're writing a proxy, you should be using the methods from Reflect to ensure that you actually preserve the behavior properly.

var handler = {
  set: function(obj, prop, value, receiver) {
    console.log(prop);

    return Reflect.set(obj, prop, value, receiver);
  }
  get: function(obj, prop, receiver) {
    if (typeof prop !== 'symbol') console.log(prop);

    return Reflect.get(obj, prop, receiver);
  }
};

The Reflect methods perform the exact original behavior that a proxy would have performed, so by using them, you avoid the dangers of not implementing them correctly yourself.

loganfsmyth
  • 156,129
  • 30
  • 331
  • 251
  • Thanks, that solved that issue. Now I'm getting a `TypeError: Illegal Invocation` – Akeem Jun 08 '18 at 23:07
  • That would require more changes to your code. I'd recommend reading over something like https://stackoverflow.com/questions/43927933/why-is-set-incompatible-with-proxy The short of it is that you're calling a function from `CanvasRenderingContext2D` but passing it a proxy instead of a real canvas, which causes an error, so you'd have to `.bind` or wrap the functions such that they are passed the correct context. – loganfsmyth Jun 08 '18 at 23:11