Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Evaluating JSON strings - eval() vs. new Function() [duplicate]

Possible Duplicate:
jQuery uses (new Function(“return ” + data))(); instead of eval(data); to parse JSON, why?

Given a string which represents a valid JSON string, is there a difference between these two parsing methods:

var str, obj;

str = '{"prop":"value"}';

// method 1:
obj = eval( '(' + str + ')' );

// method 2:
obj = ( new Function( 'return (' + str + ');' ) )();

I noticed that jQuery uses the second method to parse JSON strings (in environments that lack a built-in JSON parser). I wonder why they don't use the first method. Why create a function object and invoke it when you can just use eval()?

Please close as exact duplicate

like image 612
Šime Vidas Avatar asked Nov 22 '11 16:11

Šime Vidas


2 Answers

eval is executed within the scope it was declared. Function generates a new function object with its own scope and returns a reference to that function which can be called.

Take this example:

var x = 123;
var y;
function TestEval()
{
   var y = 1;
   Function("window.alert('Global x: ' + x);")(); //Prints 123
   Function("window.alert('Local y: ' + y);")(); //Prints undefined

   eval("window.alert('Global x: ' + x);"); //Prints 123
   eval("window.alert('Local y: ' + y);"); //Prints 1
}

TestEval();

The first two Function calls will print 123 (the global value of x) and undefined, the global value of y.

The two eval functions will print 123 and 1 (the local value of y). This is because eval has local access to the closure it's being run within. These behaviors (as well as the fact that eval is completely unreliable and inconsistent across many browsers) could be taken advantage of by the jQuery implementation.

Note: Code above tested in Firefox 8, your mileage may vary :)

like image 174
Mike Christensen Avatar answered Sep 21 '22 20:09

Mike Christensen


Using eval is evil because there can be lots of security holes. You are executing code in global scope. Function takes of this differently by executing in its own scope. But one thing Function does better is performance. Looking at this blog shows that Function is almost 2x faster in FF2.

Edit: I am not sure how much more secure it is when you execute document.location = "bad-url", it would still be executed using Function

like image 33
Amir Raminfar Avatar answered Sep 23 '22 20:09

Amir Raminfar