为什么JSON.parse(['1234'])返回1234?


75

我在了解的行为时遇到了问题JSON.parseJSON.parse应该只适用于字符串。但是,对于仅包含一个字符串(甚至用单引号引起来)的数组,如果该字符串仅包含数字,则似乎可以正常工作。

JSON.parse(['1234']) // => 1234
JSON.parse(['1234as']) // => throws error
JSON.parse(['123', '123']) // => throws error

2
我知道它们都不是无效的JSON。但是然后JSON.parse应该抛出错误,就像我在第一种情况中所预期的那样,但不是这样。
Akshendra Pratap'5

57
不要指望w3schools了解JSON。我刚刚查看了它,它在很多方面都非常错误。
Dancrumb

2
另外,我认为Solomonoff的意思是“这是JavaScript。您应该期望它符合ECMAScript规范,该规范确切解释了将非字符串传递给需要字符串的函数时会发生什么”
Dancrumb,

1
仅供参考:“连单引号”在这里都没有意义。JavaScript字符串周围的单引号和双引号与其作为JSON的有效性无关。
meagar

1
@TravisJ您对JavaScript的哪个部分以及JSON的什么部分感到困惑。JavaScript字符串中的引号在您的示例中无关紧要,并且您在两个示例中都选择了单引号,从而完全忽略了这一点。引号的JavaScript字符串,这是编码的JSON的一部分,绝对没关系,我从来没有表示他们没有。在JavaScript中用于创建字符串文字的引号不会影响该字符串中的字符是否为有效的JSON;'"foo"'和解析之间没有区别"\"foo\"",它们实际上是相同的字符串。
meagar

Answers:


179

如您所指出的,JSON.parse()期望一个字符串而不是一个数组。但是,当给定数组或任何其他非字符串值时,该方法将自动将其强制为字符串并继续执行而不是立即抛出。从规格

  1. 令JText为ToString(text)。
  2. ...

数组的字符串表示形式由其值组成,并用逗号分隔。所以

  • String(['1234'])返回'1234'
  • String(['1234as'])返回'1234as',并且
  • String(['123', '123'])返回'123,123'

注意,字符串值不再被引用。这意味着['1234'][1234]都将转换为相同的字符串'1234'

因此,您真正要做的是:

JSON.parse('1234')
JSON.parse('1234as')
JSON.parse('123,123')

1234as并且123,123不是有效的JSON,因此JSON.parse()在两种情况下均会引发。(前者不是合法的JavaScript语法,而后者包含不属于的逗号运算符。)

1234另一方面是Number文字,因此是表示自己的有效JSON。这就是为什么JSON.parse('1234')(以及扩展名JSON.parse(['1234']))返回数字值1234的原因。


12
“ ..是数字文字,因此是有效的JSON ..” -单个数字文字不是有效的JSON,但JSON.parse不是很严格(特别是,它解析JSON对象和单个值)。有关更多信息,请参见此处
BlueRaja-Danny Pflughoeft

18
@ BlueRaja-DannyPflughoeft我关注了您的链接。它不同意您的结论。如果用“有效JSON”表示“有效JSON文本”,则单个数字文字曾经是无效的,但现在是有效的。此外,“有效JSON”具有“有效JSON文本”以外的其他有效解释,并且通过其他一些解释,单个数字文字始终有效。

11
人们可以借此与一个新的水平JSON.parse(['[123', '123]']),P:
Siguza

5
@ BlueRaja-DannyPflughoeft RFC 7159和ECMA-404已修改JSON规范,以允许顶级值是数字或字符串,而不仅仅是对象或数组。JSON.parse()与此变化一致。
巴马尔(Barmar)'17年

6
@ BlueRaja-DannyPflughoeft:不幸的是,有多个版本的JSON。有Doug Crockford在JSON.org上发布的原始版本。但是,JSON也有两个国际标准,即ECMA-404(取代ECMA-262 5.1版的15.12.1节中的规范)和RFC 7159(取代RFC 4627)。另外还有...
约尔格W¯¯米塔格

22

如果JSON.parse没有获得字符串,它将首先将输入转换为字符串。

["1234"].toString() // "1234"
["1234as"].toString() // "1324as"
["123","123"].toString() // "123,123"

从所有这些输出中,它仅知道如何解析“ 1234”。


4

这里要注意两件事:

1)JSON.parse将参数转换为字符串(请参阅规范中的算法的第一步)。您的输入结果如下:

['1234']       // String 1234
['1234as']     // String 1234as
['123', '123'] // String 123,123

2)json.org上的规范指出:

[...]值可以是带双引号的字符串,也可以是数字,也可以是true或false或null,或者是对象或数组。这些结构可以嵌套。

因此,我们有:

JSON.parse(['1234'])
// Becomes JSON.parse("1234")
// 1234 could be parsed as a number
// Result is Number 1234 

JSON.parse(['1234as'])
// Becomes JSON.parse("1234as")
// 1234as cannot be parsed as a number/true/false/null
// 1234as cannot be parsed as a string/object/array either
// Throws error (complains about the "a")

JSON.parse(['123', '123'])
// Becomes JSON.parse("123,123")
// 123 could be parsed as a number but then the comma is unexpected
// Throws error (complains about the ",")
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.