开发者

Why do we need to add parentheses to eval JSON? [duplicate]

开发者 https://www.devze.com 2023-01-18 05:20 出处:网络
This question already has answers here: Why does JavaScript's eval need parentheses to eval JSON data?
This question already has answers here: Why does JavaScript's eval need parentheses to eval JSON data? (7 answers) Closed 8 years ago. 开发者_高级运维

Why does the following code needs to add ( and ) for eval?

var strJson = eval("(" + $("#status").val().replace(";","") + ")");

PS: $("#status").val() is returning something like {"10000048":"1","25000175":"2","25000268":"3"};


It depends what the value in that element is (an unknown), wrapping it in () is the safe route to account for possibly of no input being there.

Edit: Now that you've cleared up it's JSON, this isn't valid:

eval('{"10000048":"1","25000175":"2","25000268":"3"}');

But this will result in a valid object being returned:

eval('({"10000048":"1","25000175":"2","25000268":"3"})');
//effectively:
eval('return {"10000048":"1","25000175":"2","25000268":"3"};');

Picture in a JavaScript file:

<script type="text/javascript">
  {"10000048":"1","25000175":"2","25000268":"3"}
</script>

This is going to fail, it's just an object declared inline but not proper syntax...the same reason a server has to support JSONP for it to work.


A bit tangential to the question, but since you're including jQuery, you might as well use $.parseJSON() (which will use the native JSON.parse() if available) for this:

var strJson = $.parseJSON($("#status").val().replace(";",""));


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')+')');
}
0

精彩评论

暂无评论...
验证码 换一张
取 消