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:

  1. Let JText be ToString(text).
  2. ...

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 ",")