2009-06-08 85 views
33

我学会(艰难地),我需要添加的括号JSON数据,如下所示:为什么JavaScript的eval需要括号来评估JSON数据?

stuff = eval('(' + data_from_the_wire + ')'); 
// where data_from_the_wire was, for example {"text": "hello"} 

(在Firefox 3中,至少)。

背后有什么原因呢?我讨厌编写代码而不理解引擎盖后面的内容。

+1

我看你是不是以英语为母语,但“(”和“)”的括号内。如果你纠正这个问题,它可能会帮助其他人找到你的帖子。 – 2009-06-08 11:26:53

回答

38

把括号围绕data_from_the_wire实际上等同于

stuff = eval('return ' + data_from_the_wire + ';'); 

如果你不使用括号给eval,那么代码会被评估,如果你没有在它里面的任何命名函数那些将被定义,但没有返回。

以一个例子来调用就像韩中创建的功能的能力:

(function() { alert('whoot'); })() 

将调用刚刚定义的功能。下面,但是,不工作:

function() { alert('whoot'); }() 

所以我们看到,括号有效的把那么代码到返回表达式,而不只是代码运行。

-2

我不知道,我真的对这个答案感兴趣,但我的猜测是,没有括号,data_from_the_wire中的数据将被解释为闭包。也许括号强制评估,所以关联数组是'返回'。

这是导致虽然= downvotes)的那种猜测。

编辑

道格拉斯克罗克福德提到他JSON现场语法歧义,但并没有真正帮助我。

10

我不确定原因,但我使用json.orgthe JSON class来解析JSON。这比使用eval更安全。

+5

为什么downvote? 这似乎是一个有效的答案。 使用eval是不安全的。 – 2009-06-08 11:57:46

+0

他不问如何正确使用eval来解析JSON,他问为什么需要括号。 – 2012-01-08 15:01:36

62

eval接受JavaScript语句序列。 Javascript解析器 将在语句中出现的'{'标记解释为块的开始,而不是对象文本的开始。

当你把你的文字括入像这样的括号:({ data_from_the_wire }) 你正在将JavaScript解析器切换到表达式解析模式。令牌“{”的表达式的内部意味着对象文本声明的开始和的块,并且因此使用Javascript接受它作为对象常量。

2

这是因为没有JavaScript试图解释{"text": ...a label,未能圆括号。在控制台中尝试一下,你会得到“无效标签”错误。

1

它实际上取决于data_from_the_wire的值。在大多数情况下,您的语法正常,但以{开头的行会被解析为标签,并且您的语法无效。如果用圆括号括起来,它可以防止解析器误解你的表达。

只是一个解析问题,真的。用字符串,数字或函数,你不会有这个问题。

一个解决方案是总是评估指令而不是表达式。你可以写

eval('var stuff = {"text": "hello"}'); 
9

在JavaScript中,花括号用于创建语句块:

{ 
var foo = "bar"; 
var blah = "baz"; 
doSomething(); 
} 

以上线路可以把一个字符串中和eval uated没有问题。现在考虑这个:

{ 
"foo": "bar", 
"blah": "baz" 
} 

大括号导致JavaScript引擎认为它是一组表现,因此周围的:字符的语法错误。从MDN...JavaScript Guide...Object Literals引用:

您不应该在语句的开头使用对象字面值。 这将导致错误或不按预期运行,因为将被解释为块的开始。

()中包装对象字面值的解决方法是让引擎将其内容视为表达式而不是块语句。所以这不起作用:

({ 
var foo = "bar"; 
var blah = "baz"; 
doSomething(evil); 
}) 
// parse error 

但这:

({ 
"foo": "bar", 
"blah": "baz" 
}) 
// returns object