This link shows you that jQuery uses (new Function("return " + data))();
for older browsers, to parse a JSON string instead of eval()
.
What are the benefits of this? What if the JSON string isn't safe?
This link shows you that jQuery uses (new Function("return " + data))();
for older browsers, to parse a JSON string instead of eval()
.
What are the benefits of this? What if the JSON string isn't safe?
The
eval
function is very fast. However, it can compile and execute any JavaScript program, so there can be security issues. The use ofeval
is indicated when the source is trusted and competent. It is much safer to use a JSON parser. In web applications over XMLHttpRequest, communication is permitted only to the same origin that provide that page, so it is trusted. But it might not be competent. If the server is not rigorous in its JSON encoding, or if it does not scrupulously validate all of its inputs, then it could deliver invalid JSON text that could be carrying dangerous script. The eval function would execute the script, unleashing its malice.
What exactly do you mean with safe? At least malicious code is not executed ;)
See also: http://stackoverflow.com/questions/945015/alternatives-to-javascript-eval-for-parsing-json
Another point might be, that new Function()
is considered to be a little faster than eval
.
Update:
You can basically read about the same arguments in the comments on jQuery's .parseJSON()
function.
As to why jQuery specifically uses new Function()
, John Resig answered this on the jQuery forums
Using eval causes all sorts of problems for code minifiers since it's not clear what could be executing in the eval. Looking at the last results from that run it looks like new Function is fairly equivalent to eval and even slightly faster sometimes. The one exception was Safari 4 - but those results are dated, Safari 4 shipped with a native JSON.parse implementation, which we use.
The quote in Nick's answer hints at it. It's not really a big difference, but the feeling is that eval
is ‘worse’ than new Function
. Not in terms of security — they're both equally useless in the face of untrusted input, but then hopefully your webapp is not returning untrusted JSON strings — but in terms of language-level weirdness, and hence resistance to optimisation.
Specifically:
function victim() {
var a= 1;
eval('a= 2');
return a;
}
gives 2
. The eval
ed string has operated on victim
's local variable scope! This is something that a regular user-written function could never do; eval
can only do it because it is dark magic.
Using a regular function instead takes away this element of magic:
function victim() {
var a= 1;
(new Function('a= 2;'))();
return a;
}
in the above, the returned a
remains 1
; the new Function can only operate on its own local variables or the global window.a
.
That knowledge allows code analysis tools — which might include JavaScript engines and particularly clever minifiers — to apply more optimisations. For example the second victim
function could have the a
variable completely optimised away to return 1
. One use of eval
and a lot of potential optimisations aren't going to be doable.
Of course in practice for a tiny function like a JSON eval
er, there isn't going to be a noticeable difference, but in general the thinking is:
new Function
is preferable to eval
, unless you really need the code to access the calling function's local variables.