5

I'm using Chrome 60. I've just tried to apply a get Proxy on window.location.

It worked for the first two reference, however, then it failed with Illegal invocation error:

location = new Proxy(location, {
    get: (target, name) => {
        console.log(name, target, "PROX");
        return target[name];
    }
});

The error messages were:

VM3495:3 Symbol(Symbol.toPrimitive) Location {…} "PROX"

VM3495:3 toString Location {…} PROX

Uncaught TypeError: Illegal invocation at :1:10

  1. Why did it throw the error?
  2. How do I apply get Proxy on window.location in Javascript?
2
  • I'm not sure whether location can be assigned to. Commented Aug 30, 2017 at 17:32
  • @Bergi It can’t! The code was from my try to do so, though. Commented Apr 22, 2022 at 21:20

2 Answers 2

7

Why did it throw the error?

It's for the same reason why proxies are incompatible with Sets or with Maps: They are native objects, and their methods (like toString in your example) expect to be called on exactly such a native object with the respective internal slots, not a proxy.

How do I apply get Proxy on window.location in Javascript?

You need to bind all methods that the get traps intercepts to the target:

new Proxy(location, {
    get: (target, name) => {
        console.log(name, target, "PROX");
        return typeof target[name] == "function"
          ? target[name].bind(target)
          : target[name];
    }
});

However, that still doesn't change that you cannot replace the window.location global with your own implementation. It's a non-configurable property, and assigning to it will cause a navigation not write to the property.

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

Comments

0

A safer method seems to be:

new Proxy(location, {
    get: (target, prop, receiver) => {
        console.log(prop, target, "PROX");
        return Reflect.get(target, prop, target);
    }
});

Whereas regular Reflect.get(target, prop, receiver) (aka Reflect.get(...arguments)) would've been equivalent to just target[name], since the third argument to Reflect.get functions as the this for the get function. But we want our this to be of the original target, not of the new receiver.

Comments

Your Answer

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.