35

我已经(艰难地)了解到我需要在 JSON 数据周围添加括号,如下所示:

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

(至少在 Firefox 3 中)。

这背后的原因是什么?我讨厌在不了解幕后内容的情况下编写代码。

4

7 回答 7

64

eval接受一系列 Javascript 语句。Javascript 解析器将出现在语句中的“{”标记解释为块的开头,而不是对象文字的开头。

当您将文字括在这样的括号中时:({ data_from_the_wire }) 您正在将 Javascript 解析器切换到表达式解析模式。表达式中的标记“{”表示对象字面量声明的开始,而不是块,因此 Javascript 将其作为对象字面量接受。

于 2009-06-08T11:20:57.033 回答
40

将括号放在周围data_from_the_wire实际上等效于

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

如果您要在不带括号的情况下进行 eval,则将评估代码,并且如果您在其中确实有任何命名函数,则这些函数将被定义,但不会返回。

以在创建函数时调用函数的能力为例:

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

将调用刚刚定义的函数。但是,以下内容不起作用:

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

因此,我们看到括号有效地将 then 代码转换为返回的表达式,而不仅仅是要运行的代码。

于 2009-06-08T11:23:22.007 回答
11

我不确定原因,但我使用来自json.org的 JSON 类来解析 JSON 。它比使用 eval 安全得多。

于 2009-06-08T11:19:03.700 回答
9

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

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

上面的行可以放在一个字符串中并eval没有问题地使用。现在考虑一下:

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

花括号导致 JavaScript 引擎认为它是一个组表达式,因此:字符周围的语法错误。引用MDN...JavaScript 指南...对象文字

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

将对象文字包装在内部的解决方法是()告诉引擎将其内容视为表达式,而不是块语句。所以这不起作用:

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

但这确实:

({
"foo": "bar",
"blah": "baz"
})
// returns object
于 2012-04-10T07:44:45.297 回答
2

发生这种情况是因为没有圆括号 JavaScript 试图解释{"text": ...标签并失败。在控制台中尝试,您将收到“无效标签”错误。

于 2009-06-08T11:24:35.717 回答
1

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

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

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

eval('var stuff = {"text": "hello"}');
于 2009-06-08T12:56:58.570 回答
-2

我不知道,我实际上对这个问题的答案很感兴趣,但我的猜测是,如果没有括号,其中的数据data_from_the_wire将被解释为闭包。也许括号强制评估,因此关联数组被“返回”。

虽然这种猜测会导致投反对票=)。

编辑

Douglas Crockford 在他的JSON网站上提到了语法歧义,但这并没有真正帮助我。

于 2009-06-08T11:18:02.233 回答