Dandan
Dandan

Reputation: 529

Preserving the 'this' context when using JS Proxy objects

I'm trying to create a proxy to the global browser window object. The idea is simple - if the caller uses an existing method or property just return that, otherwise use the fake object. Here's the code:

var handler = {
  get: function(target, name) {
    return name in window ?
      window[name] :
      target[name];
  },
  set: function(obj, prop, value) {
    if (prop in window) {
      window[prop] = value
    } else {
      obj[prop] = value
    };
  },
};

var fakeWindow = new Proxy(function() {}, handler);
fakeWindow.foo = 'bar';
console.log(fakeWindow.foo); // outputs 'bar'
fakeWindow.alert('hello'); // error - the alert method is called without the correct this value

Problem is, when invoking a method on the proxy object (such as alert in example above), the 'this' value is that of the proxy, not the window. Is there any way to get this to work?

Upvotes: 1

Views: 953

Answers (2)

Jonas Wilms
Jonas Wilms

Reputation: 138277

You may bind the context in your getter:

get: function (target, name) {
  if (name in window) {
    if (typeof window[name] === "function") return window[name].bind(window);
    return window[name];
  }
  return target[name];
}

Upvotes: 1

Dandan
Dandan

Reputation: 529

Solution based on comment from Jonas w:

var handler = {
  get: function(target, name) {
    return name in window ?
      (typeof window[name] == 'function' ? window[name].bind(window) : window[name]) :
      target[name];
  },
  set: function(obj, prop, value) {
    if (prop in window) {
      window[prop] = value
    } else {
      obj[prop] = value
    };
  },
};

Upvotes: 0

Related Questions