【问题标题】:Why the open quote and bracket for eval('(' + jsonString+ ')') when parsing json string为什么解析 json 字符串时 eval('(' + jsonString+ ')') 的左引号和括号
【发布时间】:2011-03-22 13:57:03
【问题描述】:

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

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

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

我们可以避免吗?

【问题讨论】:

  • 如果你继续阅读你引用的那句话之后的句子,从你链接到的页面,你会明白为什么你不应该在这份工作中使用eval 完全没有
  • 我知道避免评估的原因,无论如何感谢您的指出。

标签: javascript json eval


【解决方案1】:

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

eval('{}') 未定义,例如。而eval('(' + '{}' + ')' ) 的计算结果为 Object。

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

【讨论】:

  • 你能解释一下为什么eval('{}')是未定义的吗?
  • @el.pescado:有趣的问题,请查看我的edited answer
【解决方案2】:

Crockford 所指的语法歧义是,如果在 expression 上下文中找不到左大括号,它将被识别为 block,而不是对象文字的开头.

例如:

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

会给你一个语法错误,因为它会被解释为一个块,带有字符串文字“foo”,并且意外使用了标记:

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

({"foo": "bar"})

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

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

ECMAScript 描述了一种内部类型来解释语句的行为,它被称为The Completion Specification Type

Completion 类型的值是(type, value, target) 形式的三元组,其中type 可以是normalbreakcontinuereturnthrow

value 可以是任何语言值或emptytarget 可以是任何标识符或empty

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

Return (normal, empty, empty).

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

...

7-如果result.type为normal且完成值为空,则返回值为undefined。

...

【讨论】:

【解决方案3】:

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

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

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

【讨论】:

  • A Block 被认为是一个语句,eval('{}') 不会产生任何错误,它只是一个空块。
  • var 在您传递给eval() 的字符串中似乎是非法的,您的代码是否在某些较旧的浏览器中工作(可能仅支持 ES3)?
猜你喜欢
  • 2022-07-06
  • 1970-01-01
  • 1970-01-01
  • 2016-07-02
  • 1970-01-01
  • 1970-01-01
  • 2015-08-05
  • 1970-01-01
  • 2021-11-18
相关资源
最近更新 更多