web-dev-qa-db-ja.com

JSON.parse(['1234'])が1234を返すのはなぜですか?

JSON.parseの動作を理解するのに問題があります。 JSON.parseは文字列のみで機能するはずです。しかし、文字列に数字のみが含まれている場合、1つの文字列のみを含む配列(単一引用符でも)で機能するようです。

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

あなたが指摘したように、JSON.parse()は配列ではなく文字列を期待します。ただし、配列または他の任意の非文字列値が指定されると、メソッドは自動的にそれを文字列に強制し、すぐにスローする代わりに続行します。 spec から:

  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_は数値リテラルであるため、それ自体を表す有効なJSONです。そして、それがJSON.parse('1234')(そして拡張子JSON.parse(['1234']))が数値1234を返す理由です。

180
BoltClock

JSON.parseが文字列を取得しない場合、最初に入力を文字列に変換します。

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

これらのすべての出力から、「1234」の解析方法のみがわかります。

21
naortor

ここで注意すべき2つのこと:

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 ",")
4
Salman A