views:

68

answers:

2

To parse JSON, I believe the best method is to use native JSON support in browsers.

I was looking for a good way to parse JSON in cases where native JSON support is not available.

When i looked at the code in http://www.json.org/json2.js, what i understood was it first checks whether the data is valid JSON using the regex:

if (/^[\],:{}\s]*$/.
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, '')))

and then applies eval().

jQuery performs $.parseJSON() by 1st using the above regex to check if it's valid JSON and then applies:

return window.JSON && window.JSON.parse ?
    window.JSON.parse( data ) :
        (new Function("return " + data))();

if native JSON is available it uses that, otherwise it uses "new Function".

Nowhere else did i find about using function objects for parsing JSON. Which is a better method - using eval() or function object? Can you explain what exactly does (new Function("return " + data))(); perform?

+2  A: 

new Function("return "+data) does almost the same as eval in this case. Where eval returns the result directly, (new Function("return "+data))() makes a anonymous function and executes it.

I haven't done benchmarking, but I think new Function is a bit slower than eval because a function is created first, and then the code get evaluated. Don't trust me on my word, it's just my brain thinking.

Lekensteyn
does 'new Function' remove the security issues of eval() ?
Anish
No it doesn't. That's why validating is done before.
Lekensteyn
but then why is 'new Function' used instead of 'eval'?
Anish
That could be a developer choice, but BGerissens answer is rather interesting. Found it: http://forum.jquery.com/topic/json-performance-comparison-of-eval-and-new-function
Lekensteyn
from what i understood from jquery's source, jquery validates the data even before applying native JSON parsing
Anish
Yes, that's right. [Answer](http://forum.jquery.com/topic/validating-json-unnecessarily-is-killing-firefox): *"Unfortunately the browsers aren't consistent in what JSON they are willing to parse with their JSON.parse code. For example, Chrome accepts a number of invalid strings that we need to reject. Additionally, we need to be consistent about what strings we accept and reject (and using a regular expression to double-check that makes that happen)."*
Lekensteyn
@Lekensteyn thanks for the links
Anish
http://weblogs.asp.net/yuanjian/archive/2009/03/22/json-performance-comparison-of-eval-new-function-and-json.aspx does the benchmarking for this
Anish
+1  A: 

'new Function' is a safer way of doing an eval(), with eval, all variables in the scope chain become available for the evalled code, not so with 'new Function', which does use eval() under the hood, but has no access to variables in the scope chain. Variables need to be concatenated with the passed code string.

(new Function("return " + data))();

Basically, a function is created that turns 'data' into an object and returns it, the last parenthesis () invokes the function immediatly. Since no reference to the created function is created, the garbage collector cleans the created function from the object stack.

BGerrissen