In Python, the second argument of eval() and exec() can be used to specify the "namespace" (which is an object that simulates a Python environment) in which Python code is ran. How to do the same thing in JavaScript?
2 Answers
You can't but you can take advantage of the Function constructor to create an isolate scope and prevent access to the local scope.
From MDN on new Function:
Functions created with the Function constructor do not create closures to their creation contexts [...] they will only be able to access their own local variables and global ones, not the ones from the scope in which the Function constructor was called.
From MDN on eval:
eval() is a dangerous function [...] third party code can see the scope in which eval() was invoked, which can lead to possible attacks...
So where you do:
eval('1 + 2');
You can also do:
new Function('return 1 + 2')();
As you're creating a function you can bind any context to it, an object for example:
var data = {
name: 'Peter'
};
var f = new Function('return "Hello "+ this.name;').bind(data);
f(); //=> "Hello Peter"
5 Comments
window (and possibly caller), it'd be a long stretch to read the documentation as implying it is "not dangerous". I sure wouldn't consider it any safer than eval.eval.caller (as deprecated as it may be), I have access to the "object the method was invoked upon" and all other properties (and methods) it has. The only thing that eval allows access to over Function is lexical variables who's values are not exposed via other means .. which is quite little, even with IIFEs and modules.local or data in the new Function version?Unique argument for eval is a String. You can't do the same in Javascript. You can't hard isolate a namespace so you can end with new and overwritten data. That's why eval is a well known bad practice. A code worth a thousand words:
var x = 42;
//wrapped in a self executing function for the 'namespace'
(function(){
var x; //creates a namespaced x
eval('x=69; i=function(){console.log(":( function injected");}; (function(){console.log(":( function executed");})();');
console.log("namespaced x: "+x);
})();
console.log("outer x:"+x);
i(); //This function shouldn't be here. Who wrote it? I didn't! :'(
More info: http://www.ecma-international.org/ecma-262/5.1/#sec-15.1.2.1