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

时间:2010-09-29 09:54:48

标签: javascript json

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

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

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

的内容

2 个答案:

答案 0 :(得分:4)

这取决于该元素中的值是什么(未知),将其包装在()中是考虑可能 no 输入的安全路径。

编辑:现在您已经清除它的JSON,这是无效的:

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

但是这会导致返回一个有效的对象:

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

JavaScript文件中的图片:

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

这将失败,它只是一个内联声明但没有正确语法的对象......服务器 支持JSONP使其工作的原因相同。


与此问题有点相关,但由于您要包含jQuery,因此您可以使用$.parseJSON()(如果可用,将使用本机JSON.parse()):

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

答案 1 :(得分:3)

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

作为表达:

{"10000048":"1","25000175":"2","25000268":"3"}

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

作为陈述,它是一个块:

{                       // 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

会出错。

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