- 
      
 - 
        
Save getify/2910196 to your computer and use it in GitHub Desktop.  
| sandbox (JSON) { // explicitly list everything to import from the outer scope | |
| var foobar = "baz"; // scoped to this sandbox | |
| baz = "foobar"; // still scoped to this sandbox, not auto-global. | |
| console.log(JSON); // available! | |
| console.log(window); // not available because not imported | |
| console.log(this); // undefined | |
| } | |
| console.log(baz); // undefined | 
| var foobar = sandbox() { | |
| baz = function() { // NOTE: no `var` statement necessary | |
| console.log("awesome"); | |
| }; | |
| return { | |
| baz: baz | |
| }; | |
| }; | |
| console.log(foobar.baz); // defined | |
| console.log(baz); // undefined | 
| var foobar = sandbox() { | |
| baz = function() { // NOTE: no `var` statement necessary | |
| console.log("awesome"); | |
| }; | |
| export baz; // borrowing this syntax from ES6 modules | |
| }; | |
| console.log(foobar.baz); // defined | |
| console.log(baz); // undefined | 
Custom module loaders are expected to provide that although without the syntactic sugar.
Yeah, this look like modules in strict mode (it is unfortunately not clear yet if modules will be automatically in strict mode). Blocking access to window sounds great. Module loaders should provide it as an option and it should also be a parameter for script tags, just as the sandbox parameter for iframes in HTML5, or we'll end up hacking it with iframes over and over.
There are some important differences between what i'm exploring here and ES6 modules.
Firstly, I want to avoid conflating the concept of creating scope isolation and the concept of creating a named module. There are definitely some cases where the two overlap, but there are also cases where all you want/need is scope isolation, and not all the semantics of a named module.
Secondly, I also want to avoid conflating the concept of importing scope with loading other modules. Again, there may be overlap, but in many cases, all you want to do is import a symbol, not imply that you want the host environment to instantiate a default or custom loader and block execution while it loads.
The latter point is actually my biggest beef with ES6 modules. I don't think we should combine the actions of loading and scope import into one inseparable action. If you need to load modules, you should do so yourself, asynchronously, before you need to import them into some scope isolation.
That said, borrowing the export baz syntax instead of the return { baz: ... }; syntax would be a welcome addition to what I proposed above.
Another reason I'm declaring scope symbol-imports in the sandbox declaration is that I think it should be the containing code's job to declare what scope symbols the isolation can access, not the contained code itself. I really hate the import semantics in ES6 modules for that reason (in addition to the conflation with module-loading).
I'm pretty sure we'll end up using module loaders on the web and we'll only use import in the server. I'm not sure they're specified (modules are still WIP), but I wouldn't be surprised if there can be anonymous modules.
Regarding your code... I think it's a bad bad idea to drop the var keyword. Strict mode does it right by throwing an error.
See http://www.2ality.com/2012/04/eval-variables.html
Combine that with a proxy and you're good to go.
If no proxy is available, Caja's technique is an interesting take at this problem (first file is just for context):
http://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/startSES.js
http://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/atLeastFreeVarNames.js