JSON.parse
の動作を理解するのに問題があります。 JSON.parse
は文字列のみで機能するはずです。しかし、文字列に数字のみが含まれている場合、1つの文字列のみを含む配列(単一引用符でも)で機能するようです。
JSON.parse(['1234']) // => 1234
JSON.parse(['1234as']) // => throws error
JSON.parse(['123', '123']) // => throws error
あなたが指摘したように、JSON.parse()
は配列ではなく文字列を期待します。ただし、配列または他の任意の非文字列値が指定されると、メソッドは自動的にそれを文字列に強制し、すぐにスローする代わりに続行します。 spec から:
- JTextをToString(text)にします。
- ...
配列の文字列表現は、カンマで区切られた値で構成されます。そう
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を返す理由です。
JSON.parseが文字列を取得しない場合、最初に入力を文字列に変換します。
["1234"].toString() // "1234"
["1234as"].toString() // "1324as"
["123","123"].toString() // "123,123"
これらのすべての出力から、「1234」の解析方法のみがわかります。
ここで注意すべき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 ",")