1

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 https://github.com/douglascrockford/JSON-js/blob/master/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?

Anish
  • 1,164
  • 4
  • 15
  • 27
  • Always use the native implementation if available. – Gumbo Aug 26 '10 at 12:00
  • i was wondering how to parse JSON if native implementation is not available – Anish Aug 26 '10 at 12:03
  • 1
    Note that jQuery's `parseJSON` is unsafe because it fails to escape characters U+2028 and U+2029, which are line separators in JavaScript but valid raw characters in JSON (a rather poor piece of design). `parseJSON('"hello\u2028!"');` will fail on browsers without native JSON. `json2.js` remembers to escape them in a previous step. – bobince Aug 26 '10 at 12:16

2 Answers2

2

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
  • 64,486
  • 22
  • 159
  • 192
  • does 'new Function' remove the security issues of eval() ? – Anish Aug 26 '10 at 12:04
  • but then why is 'new Function' used instead of 'eval'? – Anish Aug 26 '10 at 12:07
  • 1
    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 Aug 26 '10 at 12:09
  • from what i understood from jquery's source, jquery validates the data even before applying native JSON parsing – Anish Aug 26 '10 at 12:12
  • 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 Aug 26 '10 at 12:14
  • 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 Aug 26 '10 at 12:32
1

'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
  • 21,250
  • 3
  • 39
  • 40
  • if you want to be secure, then do `var window;` somewhere in your anonymous function. – gcb Mar 16 '13 at 01:12