为什么在解析 json 字符串时 eval('(' + jsonString+ ')') 的左引号和括号

IT技术 javascript json eval
2021-03-11 20:08:21

你能告诉我这个特定语法结构的原因吗

 eval('(' + jsonString+ ')')

解析json文本时。Crockford 说“文本必须用括号括起来,以避免在 JavaScript 语法中出现歧义。” 在这里这意味着什么?

我们能避免吗?

3个回答

Crockford 提到的语法歧义是,如果在表达式上下文中找不到左花括号,它将被识别为,而不是对象文字的开始。

例如:

{"foo": "bar"} // SyntaxError

会给你一个语法错误,因为它会被解释为一个块,带有字符串文字“foo”,以及 token 的意外用法:

另一方面,括号,正式称为分组运算符,只能计算表达式,因此我们不会有任何语法歧义,因为块只能在语句上下文中出现。

({"foo": "bar"})

编辑: @el.pescado提出了一个有趣的问题:

你能解释一下为什么 eval('{}') 是未定义的吗?

ECMAScript 描述了一个内部类型来解释语句的行为,它被称为完成规范类型

于完成类型的值是的形式的三元组(type, value, target),其中type可以是normalbreakcontinuereturn,或throw

value可以是任何语言值或empty,以及target任何标识符或empty

一个空块(生产Block : {})明确返回以下完成:

Return (normal, empty, empty).

eval函数在执行完代码后,退出新创建的执行上下文,检查所评估代码的结果完成情况,在步骤 7 中我们可以看到,undefined如果完成类型为normal,完成值为则显式返回empty

...

7- 如果 result.type 是正常的并且其完成值为空,则返回值 undefined。

...

看到这个从未发表过的博客文章草稿,关于完成类型
2021-05-03 20:08:21

对象字面量需要用括号括起来才能在eval上下文和其他上下文中正确评估

eval('{}')例如,未定义。eval('(' + '{}' + ')' )评估为对象。

例如,如果您在控制台中尝试此操作:{"foo":"bar"}它会向您抛出一个无效标签。将它括在括号中,它就成为一个有效的表达式。

@el.pescado:有趣的问题,请查看我编辑过的答案
2021-04-27 20:08:21
你能解释一下为什么eval('{}')是 undefined 吗?
2021-05-10 20:08:21

@el.pescado,eval执行后的字符串应该是javascript可以理解的。即,如果您将上述字符串分配给变量,如下所示

eval(' var foo1 = {"foo" : "bar"}'); foo1.foo 将返回 bar

所以,我的假设是,因为在 javascript 中没有像“{”这样的语句,它会抛出错误。

一个被认为是一个声明,eval('{}')不产生任何错误,它只是一个空块。
2021-04-16 20:08:21
var在您传递给的字符串中似乎是非法的eval(),您的代码是否在某些较旧的浏览器中工作(可能仅支持 ES3)?
2021-04-21 20:08:21