The following function evalCode() traces the global variables that are accessed while evaluating a piece of JavaScript code.

const _glob = typeof global !== 'undefined' ? global : self; function evalCode ( code ) { const func = new Function ( 'proxy' , `with (proxy) { ${code} }` ); const proxy = new Proxy (_glob, { get (target, propKey, receiver) { console .log( `GET ${ String (propKey)} ` ); return Reflect .get(target, propKey, receiver); }, set (target, propKey, value, receiver) { console .log( `SET ${ String (propKey)} = ${value} ` ); return Reflect .set(target, propKey, value, receiver); }, }); return func(proxy); }

The way this works is as follows:

The with statement wrapped around the code (line A) means that every variable access that “leaves” the scope of the code becomes a property access of proxy .

statement wrapped around the code (line A) means that every variable access that “leaves” the scope of the code becomes a property access of . The proxy observes what properties are accessed via its handler, which traps the operations “get” (line B) and “set” (line C),

Unsing evalCode() :

> evalCode('String.prototype') GET Symbol(Symbol.unscopables) GET String undefined > evalCode('String = 123') GET Symbol(Symbol.unscopables) SET String=123 undefined

Explanations:

We don’t return what code does, which is why the result is undefined .

does, which is why the result is . Symbol.unscopables shows up, because with checks its operand for a property with this key to determine which properties it should not expose as variables to its body. This mechanism is explained in “Exploring ES6”.

This is very hacky! with is a deprecated sloppy mode feature that is used in conjunction with a brand new ES6 feature.

Source of this hack: Vue.js, explained by qgustavor on reddit.

Further reading #