为什么 JavaScript 的 eval 需要括号来 eval JSON 数据?

IT技术 javascript json eval
2021-01-23 06:44:02

我已经知道(艰难的)我需要在 JSON 数据周围添加括号,如下所示:

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

(至少在 Firefox 3 中)。

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

6个回答

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

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

将括号括起来data_from_the_wire实际上等效于

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

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

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

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

会调用刚刚定义的函数。但是,以下方法不起作用:

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

所以我们看到括号有效地将 then 代码变成了一个返回的表达式,而不仅仅是要运行的代码。

第一部分不完全正确;eval 将字符串解释为顶级代码,因此 return 不起作用。函数的问题类似于原始问题,因为它是函数语句和函数表达式之间的歧义(请参阅 karim79 的答案)。
2021-04-07 06:44:02
我真的认为这个答案是不完整的,为什么 JSON 文字作为 的参数时eval(),必须括在括号中。@karim79 对此的回答更清楚:JSON 文字{...}将被解析为块而不是对象文字(它应该是)。
2021-04-07 06:44:02

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

他不是在问如何正确使用 eval 来解析 JSON,而是在问为什么需要括号。
2021-03-17 06:44:02
这通常是最好的答案。除非您正在处理来自安全源的大量数据,这些数据被发送到旧浏览器,该浏览器每 5,000,000 条语句显示一次错误消息。发生更换好的安全JSON.parseeval("(" + response + ")")是必要的。
2021-03-21 06:44:02
@TimČas 我意识到我没有直接回答这个问题,但是当有人用枪指着他们的脚问他们为什么需要移除安全装置时,我首先建议他们用枪指着你的脚可能不是一个好主意。
2021-03-24 06:44:02
为什么投反对票?这似乎是一个有效的答案。使用 eval 是不安全的。
2021-03-31 06:44:02
是的,但是如果我问安全气囊是如何工作的,正确的答案是描述它们是如何工作的,而不是说撞车很糟糕:)
2021-04-07 06:44:02

在 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

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