Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I watch a window.variable change with a callback?

Tags:

javascript

I have a global variable and its type is String:

window.my_global_var = 'string';

It might be changed by some external-loaded JavaScript files or an AJAX request. So I want to watch it and invoke a callback when it's updated.

I searched a while but found Object.observe is already deprecated. I found an answer but it is better used to observe an object, not a String window.variable.

The worst approach would be using a setInterval to watch it but I guess it's too stupid.

Is there any good way to do this?

like image 290
AGamePlayer Avatar asked Jun 25 '26 22:06

AGamePlayer


2 Answers

You can use Object.defineProperties on window:

function onValueUpdate(my_global_var) {
   // Some arbitrary logic you want to execute on callback
   console.log(`my_global_var was updated: ${my_global_var}`);
}

Object.defineProperties(window, {
    _my_global_var: {
        value: 'string',
        writable: true
    },
    my_global_var: {
        get: function() {
            return this._my_global_var;
        },
        set: function(val) {
            this._my_global_var = val;
            onValueUpdate(this._my_global_var);
        }
    }
});

window.my_global_var = 'New string';

When you access window.my_global_var it behaves exactly as the property of type String would. But when you set it you can adjust it to use any additional logic.

Function onValueUpdate needs to be public (or you can use a public method instead).

There’s a warning against this approach in the answer you’ve found though:

I'd not go with getters/setters solution - it's complicated, not scalable and not maintainable.

So if you need scalability you probably should look for some library that can do that. Otherwise this should work just as well.

like image 127
genechk Avatar answered Jun 28 '26 11:06

genechk


You could wrap the global object in a proxy with a set handler. You would need to pass the proxy around your program, rather than relying implicitly on the global object, however.

const handler = {
  set(obj, prop, value) {
    if (prop === 'foo')
      console.log(`Property updated with value: ${value}!`)
    return Reflect.set(...arguments)
  }
};

const proxy = new Proxy(window, handler);
proxy.foo = 1 // "Property updated with value: 1!"
proxy.bar = 2 

console.log(foo) // 1
console.log(bar) // 2
like image 28
Ben Aston Avatar answered Jun 28 '26 11:06

Ben Aston



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!