Proxy() block scope - Javascript

Viewed 341

I'm having trouble with the Proxy() object in Javascript.

This code is working as expected when I pass in a target and no handler:

const scope = new Proxy({a: 2, b: 2}, {});
with (scope) {
    a + b;
}

However, when I pass in a handler and no target, it does not work:

const scope = new Proxy({}, {get: function(){ return 2; }});
with (scope) {
    a + b;
}

scope.a == 2 && scope.b == 2 evaluates to true in both cases.

1 Answers

According to MDN, here is how JavaScript resolves variables inside with:

JavaScript looks up an unqualified name by searching a scope chain associated with the execution context of the script or function containing that unqualified name. The 'with' statement adds the given object to the head of this scope chain during the evaluation of its statement body. If an unqualified name used in the body matches a property in the scope chain, then the name is bound to the property and the object containing the property. Otherwise a ReferenceError is thrown.

That simply means with will work for static properties of scope but won't work for dynamic getters like the one you created.

This is a simple test which will help determine whether a property will be available in with or not:

const working = new Proxy({a: 2, b: 2}, {});
console.log('a' in working);

const notWorking = new Proxy({}, {get: function(){ return 2; }});
console.log('a' in notWorking);

Also, with is deprecated, here is the modern way to extract properties from an object (it's called Destructuring assignment and it works for dynamic getters as well):

const scope = new Proxy({}, {get: function(){ return 2; }});
const {a, b} = scope;
console.log(a + b);

Related