2010-09-29 84 views
5

为什么下面的代码需要为eval添加()为什么我们需要添加括号来评估JSON?

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

PS:$("#status").val()就像{"10000048":"1","25000175":"2","25000268":"3"};

+0

你为什么首先使用'eval'?只要坚持: 'var strJson = $(“#status”)。val()。replace(“;”,“”);' – 2010-09-29 10:01:45

回答

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

返回的东西这取决于什么该元素的值是(未知),在()包装是考虑到可能的没有输入的安全路线在那里。

编辑:既然你已经清除了它的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(";","")); 
+0

嗨返回的val()类似于{“10000048”:“1 ”, “25000175”: “2”, “25000268”: “3”}; – Ricky 2010-09-29 10:01:54

+0

为什么第一条语句是无效的 – Ricky 2010-09-29 10:06:20

+0

@Ricky - 这只是无效的语法,因为它不直接在脚本中,因为解析器不是将它看作表达式,而是有效地添加'()'是返回语句(因为它切换到一个表达式,识别'{'作为对象的开始,获取/返回你关心的对象)。 – 2010-09-29 10:08:08

相关问题