Why does JSON.parse(['1234']) return 1234?
I am having problems understanding the behavior of JSON.parse
. JSON.parse
should work for only strings. But it seems to work for an array which contains only one string (even single quoted), if the string contains only numbers.
JSON.parse(['1234']) // => 1234
JSON.parse(['1234as']) // => throws error
JSON.parse(['123', '123']) // => throws error
As you have pointed out, JSON.parse()
expects a string and not an array. However, when given an array or any other non-string value, the method will automatically coerce it to a string and proceed instead of throwing immediately. From the spec:
- Let JText be ToString(text).
- ...
The string representation of an array consists of its values, delimited by commas. So
-
String(['1234'])
returns'1234'
, -
String(['1234as'])
returns'1234as'
, and -
String(['123', '123'])
returns'123,123'
.
Notice that string values are not quoted again. This means that ['1234']
and [1234]
both convert to the same string, '1234'
.
So what you're really doing is:
JSON.parse('1234')
JSON.parse('1234as')
JSON.parse('123,123')
1234as
and 123,123
are not valid JSON, and so JSON.parse()
throws in both cases. (The former isn't legal JavaScript syntax to begin with, and the latter contains a comma operator that doesn't belong.)
1234
on the other hand is a Number literal and therefore valid JSON, representing itself. And that's why JSON.parse('1234')
(and by extension JSON.parse(['1234'])
) returns the numeric value 1234.
If JSON.parse doesnt get a string, it will first convert the input to string.
["1234"].toString() // "1234"
["1234as"].toString() // "1324as"
["123","123"].toString() // "123,123"
From all those outputs it only knows how to parse "1234".
Two things to note here:
1) JSON.parse
converts the argument to a string (refer to the first step of algorithm in the spec). Your input results in the following:
['1234'] // String 1234
['1234as'] // String 1234as
['123', '123'] // String 123,123
2) The specs at json.org state that:
[...] A value can be a string in double quotes, or a number, or true or false or null, or an object or an array. These structures can be nested.
So we have:
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 ",")