为什么我们需要在eval JSON中添加括号?

Ric*_*cky 5 javascript json

为什么以下代码需要添加()eval?

var strJson = eval("(" + $("#status").val().replace(";","") + ")");
Run Code Online (Sandbox Code Playgroud)

PS:$("#status").val()正在返回类似的东西{"10000048":"1","25000175":"2","25000268":"3"};

bob*_*nce 3

eval接受 JavaScript 语句或表达式,但{...}作为语句表达式是有效的,并且 JavaScript 的语法更喜欢语句。

作为一个表达式:

{"10000048":"1","25000175":"2","25000268":"3"}
Run Code Online (Sandbox Code Playgroud)

是一个具有某些属性(您想要的)的对象。

作为一个语句,它是一个块:

{                       // 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
Run Code Online (Sandbox Code Playgroud)

这给出了一个错误。

(JavaScript 标签可用于标记与break/ 一起使用的特定语句continue。它们有点毫无意义,而且几乎从未使用过。)

因此,通过添加括号可以解决歧义。只有表达式可以以 开头(,因此内容在表达式上下文中进行解析,给出对象文字,而不是语句上下文。

顺便说一句,这还不足以正确解释所有可能的 JSON 值。由于 JSON 设计中的疏忽,字符 U+2028 和 U+2029(两个晦涩的 Unicode 行结束字符)可以有效地将未转义的字符放入 JSON 字符串文字中,但不能放入 JavaScript 字符串文字中。如果你想安全,你可以逃避它们,例如:

function parseJSON(s) {
    if ('JSON' in window) return JSON.parse(s);
    return eval('('+s.replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029')+')');
}
Run Code Online (Sandbox Code Playgroud)