0

In Ecma6, it is now easy to observe changes in Object thanks to Proxy

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy

I am looking for a way to observe any variable (not only object, but also int, String..)

ex:

let s = "hello";
s = "world"; // should trigger an event when telling me that s has changed
let x=1;
x = 2; //should trigger an event when telling me that x has changed
let o = {"foo":"bar};
o.foo = "bar2"; //should trigger an event when telling me that o has changed 

Found some clues with defineProperty, but was unable to apply that to "let" variables

Listening for variable changes in JavaScript

yarek
  • 8,962
  • 25
  • 93
  • 180
  • 6
    Not possible in JS. – CertainPerformance Feb 13 '21 at 21:51
  • 2
    You could only do that by prepprocessing the source code and e.g. detect/instrument any variable assignment. That's how Svelte does it (though I don't know the details). – Felix Kling Feb 13 '21 at 21:58
  • Strong XY Problem. What would this be good for? – idmean Feb 13 '21 at 22:00
  • 2
    Sounds like what you actually want is [a debugger](https://developers.google.com/web/tools/chrome-devtools/javascript/breakpoints). See [Is there a way to set a breakpoint on a JS variable?](https://stackoverflow.com/q/38131093/1048572) – Bergi Feb 13 '21 at 22:24

1 Answers1

0

For the sake of completeness I feel like it's worth sharing that at least some of the functionality you're requesting is technically possible, though I highly recommend exploring a different approach to solving the underlying problem you have.

Use of the with statement is not recommended, as it may be the source of confusing bugs and compatibility issues.

Using a with statement and a Proxy, it's possible to trap assignments because you're actually intercepting operations on an Environment Record added into the scope. With let declarations, however, this is strictly impossible.

const handler = {
  has(target, key) {
    return typeof key === 'string';
  },
  set(target, key, value) {
    console.log(key, 'has changed');
    switch (typeof value) {
      case 'function':
      case 'object':
        value = new Proxy(value, handler);
    }
    return Reflect.set(target, key, value);
  }
};

with (new Proxy(Object.create(null), handler)) {
  s = 'world';
  x = 2;
  o = { foo: 'bar' };
  o.foo = 'bar2';
  let v = []; // not trapped
}
Patrick Roberts
  • 40,065
  • 5
  • 74
  • 116