eval
is used to evaluate a JavaScript statement or expression. However, {...}
can be valid as both a statement and an expression, but the JavaScript grammar prefers it as a statement.
When used as an expression:
{"10000048":"1","25000175":"2","25000268":"3"}
it represents an Object with properties (which is the desired outcome).
On the other hand, when used as a statement, it becomes a block:
{ // begin Block
"10000048": // LabelledStatement (quotes are invalid)
"1", // Expression that calculates string "1" then discards it, followed by
"25000175": // an attempt to put a label inside an expression
This results in an error.
(JavaScript labels are used to label specific statements for use with break
/continue
, but they are rarely utilized.)
To resolve this ambiguity, adding parentheses clarifies the context. Since only an expression can start with (
, the content inside is parsed as an expression, resulting in an object literal instead of a statement context.
It's worth noting that simply adding parentheses may not correctly interpret all JSON values. Due to a design oversight in JSON, the characters U+2028 and U+2029 (obscure Unicode line-ending characters) can be unescaped in a JSON string literal but not in a JavaScript string literal. To ensure safety, you can escape them like so:
function parseJSON(s) {
if ('JSON' in window) return JSON.parse(s);
return eval('('+s.replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029')+')');
}