Почему JSON.parse(['1234']) возвращает 1234?
У меня возникают проблемы с пониманием поведения JSON.parse
. JSON.parse
должен работать только для строк. Но, похоже, это работает для массива, который содержит только одну строку (даже одинарную кавычку), если строка содержит только числа.
JSON.parse(['1234']) // => 1234
JSON.parse(['1234as']) // => throws error
JSON.parse(['123', '123']) // => throws error
Ответы
Ответ 1
Как вы указали, JSON.parse()
ожидает строку, а не массив. Однако, когда задано массив или любое другое нестроковое значение, метод автоматически принуждает его к строке и приступает к немедленному отправке. Из spec:
- Пусть JText - ToString (текст).
- ...
Строковое представление массива состоит из его значений, разделенных запятыми. Так
-
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.
Ответ 2
Если JSON.parse не получает строку, она сначала преобразует вход в строку.
["1234"].toString() // "1234"
["1234as"].toString() // "1324as"
["123","123"].toString() // "123,123"
Из всех этих выходов он знает только, как разбирать "1234".
Ответ 3
Здесь можно отметить две вещи:
1) JSON.parse
преобразует аргумент в строку (см. первый шаг алгоритма в спецификации). Результатом ввода является следующее:
['1234'] // String 1234
['1234as'] // String 1234as
['123', '123'] // String 123,123
2) Спецификации в json.org утверждают, что:
[...] Значение может быть строкой в двойных кавычках, или числом, или истинным или 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 ",")