skip to Main Content

I am using the Javascript Proxy system to allow individual functions to subscribe to any changes in an object defined by a class. For example purposes, say this is my code:

class Data {
    i = 0
    increment() {
        this.i++;
    }
}

const obj = new Data();
const objProxy = new Proxy(obj {
    get: function(target, prop) {
        return Reflect.get(target, prop, objProxy);
    },
    set: function(target, prop, value) {
        console.log("setting", prop, "of", target);
        return Reflect.set(target, prop, value, objProxy);
    }
}

objProxy.increment();

The issue is that the this reference in the increment function is a reference to the object itself, not the proxy, so the proxy setter doesn’t seem to be triggered.

I tried to specify the object proxy as the "receiver" option for both the getter and the setter, expecting that the "this" reference would be changed to the proxy and the log message would be triggered when "i" is changed.

2

Answers


  1. It does trigger with your snippet. Make sure there are no syntax errors as I added some missing commas and brackets.

    class Data {
        i = 0
        increment() {
            this.i++;
        }
    }
    
    const obj = new Data();
    const objProxy = new Proxy(obj, {
        get: function(target, prop) {
            return Reflect.get(target, prop, objProxy);
        },
        set: function(target, prop, value) {
            console.log("setting", prop, "of", target);
            return Reflect.set(target, prop, value, objProxy);
        }
    });
    
    objProxy.increment();
    console.log(objProxy.i, obj.i);
    Login or Signup to reply.
    1. You don’t need the get trap since it does nothing
    2. You can use Reflect.set(...arguments); in a trap to shorten code
    3. You can return the proxy from the constructor so all all objects are trackable automatically
    class Data {
        constructor(){
          return new Proxy(this, {
              set: function(target, prop, value) {
                  console.log("setting", prop, "of", target);
                  return Reflect.set(...arguments);
              }
          });
        }
        i = 0
        increment() {
            this.i++;
        }
    }
    
    const obj = new Data();
    
    obj.increment();
    console.log(obj.i, obj.i);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search