Есть идеи, почему JSON не учел NaN и +/- Infinity? Это ставит Javascript в странную ситуацию, когда объекты, которые в противном случае были бы сериализуемыми, отсутствуют, если они содержат значения NaN или +/- бесконечность.
Похоже, что это было отлито из камня: см. RFC4627 и ECMA-262 (раздел 24.5.2, JSON.stringify, ПРИМЕЧАНИЕ 4, стр. 683 из документа ECMA-262 pdf при последнем редактировании):
Конечные числа выстраиваются как будто по телефону
ToString(number)
. NaN и Бесконечность независимо от знака представлены в виде строкиnull
.
javascript
json
ecma262
Джейсон С
источник
источник
Ответы:
Infinity
иNaN
не являются ключевыми словами или чем-то особенным, они являются просто свойствами глобального объекта (как естьundefined
) и, как таковые, могут быть изменены. По этой причине JSON не включает их в спецификацию - по сути, любая истинная строка JSON должна иметь такой же результат в EcmaScript, если вы это делаетеeval(jsonString)
илиJSON.parse(jsonString)
.Если бы это было разрешено, то кто-то мог бы ввести код, похожий на
в форум (или что-то еще), и тогда любое использование json на этом сайте может быть скомпрометировано.
источник
NaN
иInfinity
являются именами свойств, поэтому пока String (1/0) выдает строку,"Infinity"
которая является просто строковым представлением значения бесконечности. Это не возможно представить ниNaN
илиInfinity
как буквенные значения является ES - вы должны либо использовать выражение (например , 1/0, 0/0 и т.д.) . Или поиск свойства ( имеется в видуInfinity
илиNaN
). Так как они требуют выполнения кода, они не могут быть включены в JSON.По первоначальному вопросу: я согласен с пользователем "cbare" в том, что это неудачное упущение в JSON. IEEE754 определяет их как три специальных значения числа с плавающей запятой. Поэтому JSON не может полностью представлять числа с плавающей точкой IEEE754. На самом деле это даже хуже, поскольку JSON, как определено в ECMA262 5.1, даже не определяет, основаны ли его числа на IEEE754. Поскольку в процессе проектирования, описанном для функции stringify () в ECMA262, упоминаются три специальных значения IEEE, можно предположить, что на самом деле предполагалось поддерживать числа с плавающей запятой IEEE754.
В качестве еще одной точки данных, не связанной с вопросом: типы данных XML xs: float и xs: double do заявляют, что они основаны на числах с плавающей запятой IEEE754, и они поддерживают представление этих трех специальных значений (см. W3C XSD 1.0 Part 2 , Типы данных).
источник
Не могли бы вы адаптировать шаблон нулевого объекта и в своем JSON представить такие значения как
Затем при проверке вы можете проверить тип
Я знаю, что в Java вы можете переопределить методы сериализации, чтобы реализовать такую вещь. Не знаю, откуда твоя сериализация, поэтому я не могу подробно рассказать о том, как реализовать ее в методах сериализации.
источник
undefined
это не ключевое слово, это свойство глобального объекта"undefined" in this
возвращает значение true в глобальной области видимости. Это также означает, что вы можете сделатьundefined = 42
иif (myVar == undefined)
становится (по существу)myVar == 42
. Это возвращает нас к ранним дням экваскрипта, гдеundefined
не существовало по умолчанию, так что люди просто делали этоvar undefined
в глобальном масштабе. Следовательно,undefined
нельзя было сделать ключевое слово, не нарушая существующие сайты, и поэтому мы были обречены на все времена, чтобы undefined был обычным свойством.undefined
является глобальным свойством, потому что оно указано как таковое. Обратитесь к 15.1.1.3 из ECMAScript-262 3-е изд.Строки «Infinity», «-Infinity» и «NaN» все приводят к ожидаемым значениям в JS. Поэтому я бы сказал, что правильный способ представления этих значений в JSON - это строки.
Обидно, что JSON.stringify не делает этого по умолчанию. Но есть способ:
источник
NaN
иInfinity
добавлять в качестве значений ключевых слов, какtrue
иfalse
, хотя.Number("Infinity")
,Number("-Infinity")
иNumber("NaN")
JSON.parse("{ \"value\" : -1e99999 }")
легко вернуться{ value:-Infinity }
в JavaScript. Только это просто не совместимо с пользовательским типом номера, который может быть больше, чемЕсли у вас есть доступ к коду сериализации, вы можете представить Infinity как 1.0e + 1024. Показатель степени слишком велик для двойного представления, и при десериализации это представляется как бесконечность. Работает над webkit, не уверен насчет других парсеров json!
источник
Infinity
всегда будетInfinity
, так почему бы не поддержать это?/0
их в конец. Это легко разбирается, сразу видно и даже оценивается. Непростительно, что они еще не добавили его в стандарт: «{"Not A Number":0/0,"Infinity":1/0,"Negative Infinity":-1/0}
Почему нет?alert(eval("\"Not A Number\"") //works
alert(eval("1/0")) //also works, prints 'Infinity'
, Нет оправдания.Текущий стандарт IEEE 754-2008 включает определения для двух разных 64-битных представлений с плавающей точкой: десятичный 64-битный тип с плавающей точкой и двоичный 64-битный тип с плавающей точкой.
После округления строка
.99999990000000006
такая же, как.9999999
в двоичном 64-битном представлении IEEE, но она НЕ совпадает.9999999
с десятичным 64-битным представлением IEEE. В 64-битном IEEE десятичное число с плавающей запятой.99999990000000006
округляется до значения,.9999999000000001
которое не совпадает с десятичным.9999999
значением.Поскольку JSON просто обрабатывает числовые значения как числовые строки десятичных цифр, система, которая поддерживает двоичные и десятичные представления с плавающей точкой IEEE (например, IBM Power), не может определить, какое из двух возможных числовых значений с плавающей точкой IEEE является предназначена.
источник
Потенциальный обходной путь для таких случаев, как {"key": Infinity}:
Общая идея состоит в том, чтобы заменить вхождения недопустимых значений строкой, которую мы распознаем при разборе, и заменить ее соответствующим представлением JavaScript.
источник
Причина указана на странице ii в стандарте ECMA-404. Синтаксис обмена данными JSON, 1-е издание
Причина не в том, как многие утверждали, из-за представлений
NaN
иInfinity
сценария ECMA. Простота является основным принципом проектирования JSON.источник
Если, как и я, у вас нет контроля над кодом сериализации, вы можете иметь дело со значениями NaN, заменив их нулевым или любым другим значением, что выглядит как хакерство следующим образом:
По сути, .fail будет вызван, когда оригинальный анализатор json обнаружит недопустимый токен. Затем для замены недопустимых токенов используется строка replace. В моем случае это исключение для сериализатора, возвращающего значения NaN, поэтому этот метод является лучшим подходом. Если результаты обычно содержат недопустимый токен, лучше не использовать $ .get, а вместо этого вручную извлекать результат JSON и всегда выполнять замену строки.
источник
{ "tune": "NaNaNaNaNaNaNaNa BATMAN", "score": NaN }