2

Can I proxy the window object to detect changes? I tried the following without any luck:

var handler = {
  get: function(target, property) {
    console.log("getting " + property + " for " + target);
    return target[property];
  },
  set: function(target, property, value, receiver) {
    console.log("setting " + property + " for " + target + " with value " + value);
    target[property] = value;
    return true;
  },
};
var p = new Proxy(window, handler);
setTimeout(() => {
  window.a = 10; // expecting a log, but nothing...
}, 3000);
setTimeout(() => {
  window.c = 20; // expecting a log, but nothing...
}, 4000);

1 Answer 1

5

You have to reference the Proxy instance in your lower code, not the window:

var handler = {
  get: function(target, property) {
    console.log("getting " + property + " for " + target);
    return target[property];
  },
  set: function(target, property, value, receiver) {
    console.log("setting " + property + " for " + target + " with value " + value);
    target[property] = value;
    return true;
  },
};
var p = new Proxy(window, handler);

setTimeout(() => {
  p.a = 10;    // <------------
}, 300);
setTimeout(() => {
  p.c = 20;    // <------------
}, 400);

If you can't change the code that references the window, you could also name the proxy window (and save a reference to the true window in another variable), but the code for that would look confusing.

If it's in a standalone script file, the above trick won't work, and you won't be able to use a Proxy - you can't redefine the window object, after all. If you're looking for a change for a specific property on window, you could use defineProperty and have the setter overwrite the property descriptor with the new value when it gets assigned to:

Object.defineProperty(window, 'a', {
  configurable: true,
  set(value) {
    console.log("setting with value " + value);
    Object.defineProperty(window, 'a', { value });
  }
});

setTimeout(() => {
  window.a = 10;
  console.log(window.a);
}, 300);

Sign up to request clarification or add additional context in comments.

4 Comments

But I only need to detect changes on window. The use case is to check if window.pluginX then initialise the plugin. Because the plugin, when loaded, adds a prop pluginX to window so I just need to check that and do my thing.
@eozzy were you able to resolve this? I also want to listen to changes in a window property and based on that make changes to global variable which is pointing to that window property.
@ZameerHaque Make the window property you want to listen to into a getter/setter.
Yes, ended up doing that. Proxying would have been great, as the shared module which accesses the window property would not have to change the signature for calling the property.

Your Answer

Draft saved
Draft discarded

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.