In ECMAScript 6 it's more or less possible by wrapping the code inside a with
statement with a proxy object. Note it requires non-strict mode and it's bad practice.
function storeVars(target) {_x000D_
return new Proxy(target, {_x000D_
has(target, prop) { return true; },_x000D_
get(target, prop) { return (prop in target ? target : window)[prop]; }_x000D_
});_x000D_
}_x000D_
var vars = {}; // Outer variable, not stored._x000D_
with(storeVars(vars)) {_x000D_
var a = 1; // Stored in vars_x000D_
var b = 2; // Stored in vars_x000D_
(function() {_x000D_
var c = 3; // Inner variable, not stored._x000D_
})();_x000D_
}_x000D_
console.log(vars);
_x000D_
The proxy claims to own all identifiers referenced inside with
, so variable assignments are stored in the target. For lookups, the proxy retrieves the value from the proxy target or the global object (not the parent scope). let
and const
variables are not included.
Inspired by this answer by Bergi.