eval
takes a JavaScript statement or expression, but {...}
would be valid as a statement or an expression, and the grammar of JavaScript prefers a statement.
As an expression:
{"10000048":"1","25000175":"2","25000268":"3"}
is an Object with some properties (what you want).
As a statement, it is a block:
{ // begin Block
"10000048": // LabelledStatement (but the quotes are invalid)
"1", // Expression, calculate string "1" then discard it, then
"25000175": // you can't put a label inside an expression
which gives an error.
(JavaScript labels can be used to label a particular statement for use with break
/continue
. They're a bit pointless and almost never used.)
So by adding the parentheses you resolve the ambiguity. Only an expression can start with (
, so the contents are parsed in an expression context, giving an object literal, not a statement context.
Incidentally this is not quite enough to correctly interpret all possible JSON values. Due to an oversight in JSON's design, the characters U+2028 and U+2029, two obscure Unicode line-ending characters, are valid to put unescaped in a JSON string literal, but not in a JavaScript string literal. If you want to be safe, you can escape them, eg:
function parseJSON(s) {
if ('JSON' in window) return JSON.parse(s);
return eval('('+s.replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029')+')');
}