0

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
  • 2
    You can't. JavaScript has just about zero introspective capabilities. Commented Dec 13, 2013 at 7:43
  • if i understand right you need see about bind function Commented Dec 13, 2013 at 7:47

2 Answers 2

2

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"
Sign up to request clarification or add additional context in comments.

5 Comments

Since the code in the Function body still can run arbitrary JS and has access to 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.
Yes, it's still unsafe in that aspect, but if you follow best practices and wrap everything in IIFE and only expose a unique namespace, it's still safer than a local eval.
As soon as I have access to 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.
I'm not exactly sure how to do that... I put a little example here, jsbin.com/oGiFaQAl/2/edit. How would you access local or data in the new Function version?
That's super trivial example and doesn't violate the concessions in my previous comments. Try with a module that returns an actual object with properties/methods :) One the values actually enter an exposed object graph (including the DOM), then they become fair game.
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.