JSON не включает Infinity и NaN; Статус JSON в ECMAScript?

Есть идеи, почему JSON не учел NaN и +/- Infinity? Это ставит Javascript в странную ситуацию, когда объекты, которые в противном случае были бы сериализуемыми, не являются сериализуемыми, если они содержат значения NaN или +/- бесконечности.

Похоже, это высечено на камне: см. RFC4627 и ECMA-262 (раздел 24.5.2, JSON.stringify, ПРИМЕЧАНИЕ 4, стр. 683). ECMA-262 pdf при последнем редактировании):

Конечные числа преобразуются в строки, как если бы они вызывали ToString(number). NaN и Infinity независимо от знака представлены строкой null.


person Jason S    schedule 14.09.2009    source источник
comment
Я не могу найти эту цитату ни в одном документе.   -  person wingedsubmariner    schedule 24.08.2015
comment
исправил это, похоже, что каким-то образом была устаревшая ссылка / устаревшее редактирование.   -  person Jason S    schedule 24.08.2015
comment
dbj.org/json-how -to-create-an-undefined-value-or-nan-value   -  person Chef Gladiator    schedule 07.02.2020


Ответы (10)


Infinity и NaN не являются ключевыми словами или чем-то особенным, это просто свойства глобального объекта (как и undefined), и поэтому их можно изменить. Именно по этой причине JSON не включает их в спецификацию — по сути, любая истинная строка JSON должна иметь тот же результат в EcmaScript, если вы делаете eval(jsonString) или JSON.parse(jsonString).

Если бы это было разрешено, кто-то мог бы ввести код, похожий на

NaN={valueOf:function(){ do evil }};
Infinity={valueOf:function(){ do evil }};

в форум (или что-то еще), и тогда любое использование json на этом сайте может быть скомпрометировано.

person olliej    schedule 14.09.2009
comment
Где сказано, что Infinity и NaN являются ключевыми словами? Это двойные значения Javascript. - person Jason S; 15.09.2009
comment
Если вы оцениваете 1/0, вы получаете бесконечность, если вы оцениваете -1/0, вы получаете -бесконечность, если вы оцениваете 0/0, вы получаете NaN. - person Jason S; 15.09.2009
comment
Но термины NaN и Infinity являются именами свойств, поэтому в то время как String(1/0) создает строку "Infinity", которая является просто строковым представлением бесконечности значения. Невозможно представить ни NaN, ни Infinity, поскольку буквенные значения являются ES - вам нужно либо использовать выражение (например, 1/0, 0/0 и т. д.), либо поиск свойства (ссылаясь на Infinity или NaN). Поскольку они требуют выполнения кода, они не могут быть включены в JSON. - person olliej; 15.09.2009
comment
Мне нравится, как вы решили проголосовать против единственного ответа, который говорит, почему NaN и Infinity не разрешены - JSON специально разработан как подмножество языка ES, которое разрешает только литералы и любой доступ к свойствам по определению не является литералом. - person olliej; 15.09.2009
comment
Попробуйте запустить консоль jsdb или Firebug: NaN={toString: function() { return fiddledeedee }}, а затем запустите 0/0, чтобы получить внутренний объект NaN; не могу переопределить. - person Jason S; 17.09.2009
comment
NaN и Infinity не являются именами свойств (возможно, они есть в JScript IE). - person Jason S; 17.09.2009
comment
Что касается вашей точки зрения о безопасности/безопасности, все, что должен сделать приличный анализатор JSON, когда он переходит к преобразованию NaN, - это получить значение 0/0 (вместо оценки символа NaN), которое вернет реальный NaN независимо от того, какой символ NaN переопределяется как. - person Jason S; 17.09.2009
comment
@Jason-S: 0/0 не возвращает внутренний объект NaN — вы не понимаете, что происходит. если я сделаю 0/0, у меня теперь будет число со значением, а не числом. Если я хочу отобразить его (например, alert(0/0) или что-то еще), вам нужно преобразовать число в строку, это делается внутренней функцией ES [[ToString]]. Для числа [[ToString]] определяется как возврат строк -Infinity, Infinity или NaN в зависимости от ситуации: вы не видите какой-то магический новый объект, вы видите строковое представление числа. - person olliej; 17.09.2009
comment
@Jason S: В вашем примере вас излишне усложняют. NaN=4; alert(NaN == 4). Дело в безопасности JSON заключается в том, что это подмножество синтаксиса ES, которое допускает только литералы — если он разрешает NaN или Infinity, он больше не ограничивается только литералами и, следовательно, может привести к выполнению кода и, следовательно, может быть небезопасным. - person olliej; 17.09.2009
comment
@Jason S: Вы не можете сказать, что синтаксический анализатор JSON может просто ограничить его, потому что тогда а) JSON больше не будет подмножеством ES, и б) существует достаточно кода, использующего простой вызов eval для анализа JSON, что позволяет JSON включение нелитералов означало бы, что действительный JSON может привести к выполнению кода. NaN и Infinity — это имена свойств, в выбранной вами js-консоли сделайте "NaN" in this и "Infinity" in this или более жестоко Infinity = 0; alert(Infinity == 1/0) и т. д. Infinity и NaN — это свойства глобального объекта, которые относятся к числам со значением бесконечность или не являются числами. - person olliej; 17.09.2009
comment
@Jason S: Если вы по-прежнему не верите мне, посмотрите на спецификацию ES - см. Раздел 15.1.1 спецификаций ECMA262-3 или ECMA262-5 (Свойства значений глобального объекта) - person olliej; 18.09.2009
comment
@olliej: NaN=4; alert(NaN == 4) излишне прост; значение символа NaN (которое по умолчанию равно встроенному значению NaN), если оно переопределено таким образом, не имеет ничего общего со встроенным значением NaN. Мы в разговорном тупике... Я понимаю вашу точку зрения о том, что строки JSON больше нельзя безопасно анализировать с помощью простого вызова eval(). Но простой вызов eval() небезопасен, и если синтаксический анализатор JSON достаточно умен, чтобы ограничить содержимое строки перед вызовом eval(), то он достаточно умен, чтобы заменить NaN на (0/0), а Infinity на (1/0). ), что решит проблему. - person Jason S; 18.09.2009
comment
FWIW, вы немного подумали над своим первоначальным ответом, который я теперь понимаю ... извиняюсь за отрицательный голос, и если вы сделаете токен редактирования (просто добавьте пробел или что-то еще), я отменю отрицательный голос. - person Jason S; 18.09.2009
comment
Где вы хотите пространство? мне это кажется довольно ясным (но тогда я работаю над одной из реализаций ES, поэтому, возможно, я не знаю о двусмысленности, которая присутствует, если люди не знают, как работают JS-движки) - person olliej; 18.09.2009
comment
этот сайт не позволяет вам удалять отрицательные голоса, если пост не отредактирован, вот и все - person Jason S; 18.09.2009
comment
Действительно? Я так и не понял :-( - person olliej; 18.09.2009
comment
@olliej: вы утверждаете, что NaN не является буквальным, я недостаточно знаю Javascript, чтобы судить о семантике javascript. Но для формата файла, в котором хранятся числа с плавающей запятой двойной точности, должен быть способ определить числа с плавающей запятой IEEE, то есть с помощью литералов NaN/Infinity/NegInfinity. Это состояния 64-битных двойников, и поэтому они должны быть представимы. Есть люди, которые зависят от них (по причинам). Они, вероятно, были забыты, потому что JSON/Javascript возникли в веб-разработке, а не в научных вычислениях. - person wirrbel; 27.06.2013
comment
@wirrbel, я полностью согласен с тем, что эти значения должны быть представлены в JSON. Что касается проблем с выполнением кода: если код, анализирующий JSON, ранее испортил NaN, то это программист решил изменить это. Это не уязвимость удаленного выполнения. По крайней мере, не более чем: String.prototype.indexOf=function(){throw new Error('Crash!')};, за которым в какой-то момент следует obj=JSON.parse(remoteString);alert((obj.prop||"").indexOf('ok'));. Опять же, это программист решил возиться с классом String, а JSON только ссылается на него, но не диктует, что он делает. - person DDS; 11.11.2013
comment
вы обсуждаете неправильные вещи. JSON не должен быть eval. JavaScript содержит внутренние объекты NaN и Infinity/-Infinity. этот ответ не дает причин, по которым Крокфорд просто не указал бы, что JSON может кодировать эти внутренние объекты с использованием этих выражений. - person flying sheep; 06.06.2014
comment
Требование того же результата, что и eval, кажется глупым ограничением для JSON. Вы не должны использовать eval даже в JSON. В результате в определенных ситуациях вы не можете делать то, что вам действительно нужно, не прыгая через обручи. Одна из лучших особенностей JSON заключается в том, что он в значительной степени позволяет избежать необходимости прыгать через обручи для передачи ваших данных. JSON — это формат обмена данными (и очень хороший!), который широко используется во многих языках программирования. А как насчет eval функций языков помимо JavaScript? Должен ли он пытаться поддерживать их? - person jpmc26; 31.12.2014
comment
Аргумент безопасности, приведенный здесь, нелеп. Если у кого-то есть разрешение на внедрение javascript, как описано в ответе, у людей, посещающих этот сайт, есть гораздо более серьезные проблемы с безопасностью, о которых нужно беспокоиться. - person Bennidhamma; 09.06.2015
comment
Это 100%, абсолютно НЕПРАВИЛЬНО для JSON произвольно опускать совершенно действительные и стандартные состояния чисел с плавающей запятой NaN, Infinity и -Infinity. По сути, JSON решил поддерживать произвольное подмножество значений с плавающей запятой IEEE, по незнанию пропуская три конкретных значения, потому что они сложные или что-то в этом роде. Нет. Eval-способность — это даже не оправдание, потому что такие числа могли быть закодированы как литералы 1/0, -1/0 и 0/0. Это будут действительные числа, к которым добавлен /0, что не только просто обнаружить, но и в то же время фактически оценить как ES. Нет оправдания. - person Triynko; 08.09.2015
comment
Кроме того, без поддержки этих трех четко определенных результатов наиболее фундаментальной математической операции деления JSON не может утверждать, что поддерживает числа с плавающей запятой IEEE754, и, что еще хуже, он даже не удосуживается заявить об этом. Отключение от стандарта также не дает никаких преимуществ, потому что, даже если это может позволить произвольно большие числа... это не только бесполезно на практике (удачи в том, чтобы запихнуть нестандартное число в любую реальную переменную и сделать что-нибудь с ним.... можно также использовать строку с пользовательским синтаксическим анализатором в этот момент), но это навсегда останется неадекватным. - person Triynko; 08.09.2015
comment
Ваш код инъекции не работает в последних версиях Chrome и Firefox. Нет практической причины избегать их. - person Marco Sulla; 15.03.2016
comment
Ну, если кто-то может внедрить какой-либо код, использование javascript будет скомпрометировано... - person IcanDivideBy0; 03.11.2016
comment
Бесконечность и NaN не являются чем-то особенным? НЕПРАВИЛЬНЫЙ. Это по этой причине? НЕПРАВИЛЬНЫЙ. Аргумент безопасности также абсолютно НЕПРАВИЛЬНЫЙ. Единственное правильно, что JSON можно разобрать как JS, что не объясняет ничего полезного для вопроса. Объясните мне, как 74 человека проголосовали за это. - person Pierre; 14.03.2017
comment
JSON не является подмножеством ES, и eval и JSON.parse в некоторых случаях уже дают разные результаты. Примечательно, что JSON допускает необработанные символы \u2028 и \u2029 в строках, а Ecmascript — нет. - person Antimony; 12.12.2017
comment
Плохой выбор, сделанный реализатором, не делает этот ответ плохим.... - person meawoppl; 07.09.2018
comment
@Antimony Последний ECMAScript теперь является расширенным набором JSON, - person Simon Buchan; 30.04.2019
comment
Сценарий ECMA не имеет к этому никакого отношения, см. страницу ii ecma-international.org/publications/files/ECMA-ST-ARCH/ - person CervEd; 10.10.2019
comment
Пока NaN и Infinity не являются литералами в Javascript, на самом деле не имеет значения, как их определяет IEEE (или любая другая спецификация), к ним не следует относиться с допущением безопасности литералов в JSON. - person Edy; 27.05.2020
comment
Вот почему JSON никогда не следует оценивать, а только анализировать! - person Luke Hutchison; 01.07.2021

По исходному вопросу: я согласен с пользователем «cbare» в том, что это досадное упущение в JSON. IEEE754 определяет их как три специальных значения числа с плавающей запятой. Таким образом, JSON не может полностью представлять числа с плавающей запятой IEEE754. На самом деле это еще хуже, поскольку JSON, как определено в ECMA262 5.1, даже не определяет, основаны ли его числа на IEEE754. Поскольку процесс разработки, описанный для функции stringify() в ECMA262, действительно упоминает три специальных значения IEEE, можно предположить, что на самом деле целью была поддержка чисел с плавающей запятой IEEE754.

В качестве еще одной точки данных, не связанной с вопросом: типы данных XML xs:float и xs:double действительно заявляют, что они основаны на числах с плавающей запятой IEEE754, и они поддерживают представление этих трех специальных значений (см. W3C XSD 1.0, часть 2). , Типы данных).

person Andreas Maier    schedule 09.02.2012
comment
Я согласен, что все это печально. Но, возможно, хорошо, что числа JSON не указывают точный формат с плавающей запятой. Даже IEEE754 определяет множество форматов — разные размеры и различие между десятичными и двоичными показателями. JSON особенно хорошо подходит для десятичной системы счисления, поэтому было бы жаль, если бы какой-то стандарт привязывал его к двоичной системе. - person Adrian Ratnapala; 03.05.2014
comment
@AdrianRatnapala +1 Действительно: числа JSON имеют потенциально бесконечную точность, поэтому они намного лучше спецификаций IEEE, поскольку у них нет ограничений по размеру, точности и эффекта округления (если сериализатор может с этим справиться). - person Arnaud Bouchez; 30.01.2015
comment
@ArnaudBouchez. Тем не менее, JSON по-прежнему должен поддерживать строки, представляющие NaN и +-Infinity. Даже если JSON не следует привязывать к какому-либо формату IEEE, люди, определяющие числовой формат, должны хотя бы взглянуть на страницу википедии IEEE754 и немного подумать. - person Adrian Ratnapala; 31.01.2015
comment
comment
В этом нет ничего плохого. Смотрите ответ @CervEd. Он не привязан к IEE754, что хорошо (даже если большинство языков программирования используют IEEE754 и, следовательно, требуют дополнительной обработки в случае NaN и т. д.). - person Ludovic Kuty; 10.03.2020

Не могли бы вы адаптировать шаблон нулевого объекта и в своем JSON представить такие значения, как

"myNum" : {
   "isNaN" :false,
   "isInfinity" :true
}

Затем при проверке вы можете проверить тип

if (typeof(myObj.myNum) == 'number') {/* do this */}
else if (myObj.myNum.isNaN) {/* do that*/}
else if (myObj.myNum.isInfinity) {/* Do another thing */}

Я знаю, что в Java вы можете переопределить методы сериализации, чтобы реализовать такую ​​​​вещь. Не уверен, откуда вы сериализуете, поэтому я не могу подробно рассказать, как это реализовать в методах сериализации.

person Zoidberg    schedule 14.09.2009
comment
хммм... это ответ на обходной путь; На самом деле я просил не обходной путь, а то, почему эти значения исключались. Но +1 все равно. - person Jason S; 14.09.2009
comment
Что касается почему, я не уверен, почему они пропустили это. Возможно, они ожидают, что вы будете использовать максимальное и минимальное значения для конкретного числа, например Integer.MAX_VALUE. Вплоть до И.Э. 5.5 у них даже не было ключевого слова null в javascript (по крайней мере, для IE, который отстой), вы даже не могли использовать ключевое слово undefined, что значительно усложняло javascript. Это может быть то же самое, возможно, браузеры примут это в будущем. - person Zoidberg; 14.09.2009
comment
@Zoidberg: undefined - это не ключевое слово, это свойство глобального объекта. - person olliej; 15.09.2009
comment
@olliej: если (myVar == undefined) и undefined находится в глобальном объекте? Я не понимаю, можно поподробнее? - person Zoidberg; 15.09.2009
comment
@Zoidberg: undefined - это свойство глобального объекта - это не ключевое слово, поэтому "undefined" in this возвращает true в глобальной области. Это также означает, что вы можете сделать undefined = 42, а if (myVar == undefined) станет (по сути) myVar == 42. Это восходит к ранним дням ecmascript, урожденного javascript, где undefined не существовало по умолчанию, поэтому люди просто делали var undefined в глобальной области видимости. Следовательно, undefined нельзя было сделать ключевым словом, не нарушая существующие сайты, и поэтому мы навсегда обречены на то, чтобы undefined было нормальным свойством. - person olliej; 16.09.2009
comment
@olliej: Круто, я понятия не имел, что это действительно имеет смысл. То же самое касается нуля? - person Zoidberg; 16.09.2009
comment
@olliej: я понятия не имею, почему вы думаете, что undefined является свойством глобального объекта. По умолчанию поиск undefined — это встроенное значение undefined. Если вы переопределите его с помощью undefined=42, то при доступе к undefined в качестве поиска переменной вы получите переопределенное значение. Но попробуйте сделать zz=undefined; не определено=42; х={}; 'undefined old='+(x.a === zz)+', undefined new='+(x.a === undefined). Вы никогда не сможете переопределить внутренние значения null, undefined, NaN или Infinity, даже если вы можете переопределить их поиск символов. - person Jason S; 17.09.2009
comment
@Jason undefined является глобальным свойством, поскольку оно указано как таковое. См. 15.1.1.3 ECMAScript-262, 3-е изд. - person kangax; 18.09.2009
comment
@olliej Но когда я делаю this.undefined = 42; console.log(this.undefined); в консоли Firefox, я получаю undefined в журнале. То есть вы правы только наполовину, я не могу изменить значения undefined, NaN и Infinity (проверил все). - person kstep; 22.11.2012

Строки «Infinity», «-Infinity» и «NaN» приводятся к ожидаемым значениям в JS. Поэтому я бы сказал, что правильный способ представления этих значений в JSON — это строки.

> +"Infinity"
Infinity

> +"-Infinity"
-Infinity

> +"NaN"
NaN

Жаль, что JSON.stringify не делает этого по умолчанию. Но есть способ:

> JSON.stringify({ x: Infinity }, function (k,v) { return v === Infinity ? "Infinity" : v; })
"{"x":"Infinity"}"
person teh_senaus    schedule 27.02.2015
comment
0/0 и т. д. недопустимы в формате JSON. Вы должны работать в рамках стандарта, и строки прекрасно справляются с этой задачей. - person teh_senaus; 08.09.2015
comment
Напротив, я думаю, что это единственное практичное решение, но я сделаю функцию, которая возвращает NaN, если входное значение равно NaN и т. д. Способ, которым вы выполняете преобразование, подвержен внедрению кода. - person Marco Sulla; 15.03.2016
comment
Значения JSON не могут быть арифметическими выражениями... цель отделения стандарта от литерального синтаксиса языка состоит в том, чтобы сделать JSON десериализуемым, не выполняя его как код. Не знаю, почему мы не могли добавить NaN и Infinity в качестве значений ключевых слов, таких как true и false. - person Mark Reed; 18.04.2016
comment
Чтобы сделать его более явным, мы можем использовать Number("Infinity"), Number("-Infinity") и Number("NaN"). - person HKTonyLee; 30.11.2017
comment
Это работает как по волшебству.JSON.parse("{ \"value\" : -1e99999 }") легко вернуть { value:-Infinity } в javascript. Только он просто не совместим с пользовательским типом номера, который может быть больше этого - person Thaina; 20.05.2020

Если у вас есть доступ к коду сериализации, вы можете представить Infinity как 1.0e+1024. Показатель степени слишком велик, чтобы представлять его в виде двойного числа, и при десериализации это представляется как бесконечность. Работает на webkit, не уверен насчет других парсеров json!

person kuwerty    schedule 20.02.2012
comment
IEEE754 поддерживает 128-битные числа с плавающей запятой, поэтому 1.0e5000 лучше. - person Ton Plomp; 06.10.2012
comment
Тон: 128 бит добавили позже. Что, если они решат добавить 256 бит? Тогда вам придется добавить больше нулей, и существующий код будет вести себя по-другому. Infinity всегда будет Infinity, так почему бы не поддержать это? - person flying sheep; 06.06.2014
comment
Умная идея! Я как раз собирался либо переключиться на другой формат, либо добавить громоздкий обходной код в свой парсер. Не идеально для каждого случая, но в моем случае, когда бесконечность служит просто оптимизированным граничным случаем для сходящейся последовательности, это просто идеально, и даже если будет введена большая точность, это все равно будет в основном правильно. Спасибо! - person Or Sharir; 31.05.2015
comment
1, -1 и 0... абсолютно допустимые/поддающиеся анализу числа становятся теми тремя специальными значениями, когда вы просто добавляете /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'. Нет оправдания. - person Triynko; 08.09.2015
comment

Причина указана на странице ii в Стандарт ECMA-404 Синтаксис обмена данными JSON, 1-е издание

JSON не зависит от чисел. В любом языке программирования может быть множество типов чисел различной разрядности и дополнений, фиксированных или с плавающей запятой, двоичных или десятичных. Это может затруднить обмен между разными языками программирования. Вместо этого JSON предлагает только представление чисел, которое используют люди: последовательность цифр. Все языки программирования умеют понимать последовательности цифр, даже если они расходятся во внутренних представлениях. Этого достаточно для обмена.

Причина не в представлениях NaN и Infinity сценария ECMA, как утверждают многие. Простота — основной принцип проектирования JSON.

Поскольку это так просто, не ожидается, что грамматика JSON когда-либо изменится. Это дает JSON, как основополагающей нотации, потрясающую стабильность.

person CervEd    schedule 10.10.2019
comment
...только представление чисел, которое используют люди... Значит, математики, ученые, инженеры и программисты, использующие символ бесконечности, не являются людьми? (Снарк нацелен на стандарт, а не на CervEd.) - person Emile Cormier; 14.07.2021

Возможный обходной путь для таких случаев, как {"key":Infinity}:

JSON.parse(theString.replace(/":(Infinity|-IsNaN)/g, '":"{{$1}}"'), function(k, v) {
   if (v === '{{Infinity}}') return Infinity;
   else if (v === '{{-Infinity}}') return -Infinity;
   else if (v === '{{NaN}}') return NaN;
   return v;
   });

Общая идея состоит в том, чтобы заменить вхождения недопустимых значений строкой, которую мы распознаем при анализе, и заменить ее соответствующим представлением JavaScript.

person SHamel    schedule 03.08.2018
comment
Я не знаю, почему это решение получило отрицательную оценку, потому что, честно говоря, если вы столкнетесь с ситуацией, когда ваша строка JSON содержит значения Infinity или IsNaN, она потерпит неудачу при попытке ее анализа. Используя этот метод, вы сначала заменяете вхождения IsNaN или Infinity чем-то другим (чтобы изолировать их от любой действительной строки, которая может содержать эти термины), и используете JSON.parse(string,callback) для возврата правильных допустимых значений JavaScript. Я использую это в производственном коде и никогда не имел проблем. - person SHamel; 08.07.2019
comment
Не испортит ли это Infinity внутри струн? Для многих вариантов использования, вероятно, можно с уверенностью предположить, что это не проблема, но решение не является полностью надежным. - person olejorgenb; 28.05.2020

JSON5 допускает стандартную нотацию Javascript для положительной и отрицательной бесконечности, NaN и многих других вещей, которые являются действительными ECMAScript, которые были исключены из JSON (конечные запятые и т. д.).

https://json5.org/

Это делает JSON гораздо более полезным форматом.

Однако, независимо от того, используете ли вы JSON или JSON5: из соображений безопасности всегда всегда анализируйте -- не оценивайте!!

person Luke Hutchison    schedule 01.07.2021

Текущий IEEE Std 754-2008 включает определения для двух различных 64-битных представлений с плавающей запятой: десятичного 64-битного типа с плавающей запятой и двоичного 64-битного типа с плавающей запятой.

После округления строка .99999990000000006 совпадает с .9999999 в двоичном 64-битном представлении IEEE, но НЕ совпадает с .9999999 в десятичном 64-битном представлении IEEE. В 64-битном IEEE десятичное число с плавающей запятой .99999990000000006 округляется до значения .9999999000000001, которое не совпадает с десятичным значением .9999999.

Поскольку JSON просто обрабатывает числовые значения как числовые строки десятичных цифр, система, которая поддерживает как двоичные, так и десятичные представления с плавающей запятой IEEE (например, IBM Power), не может определить, какое из двух возможных числовых значений IEEE с плавающей запятой является предназначена.

person Steven Hobbs    schedule 27.10.2015
comment
Какое это имеет отношение к вопросу? (что касается Infinity и NaN) - person Bryan; 03.01.2019

Если, как и я, у вас нет контроля над кодом сериализации, вы можете иметь дело со значениями NaN, заменив их нулевым значением или любым другим значением, например, следующим образом:

$.get("file.json", theCallback)
.fail(function(data) {
  theCallback(JSON.parse(data.responseText.replace(/NaN/g,'null'))); 
} );

По сути, .fail будет вызываться, когда исходный анализатор json обнаружит недопустимый токен. Затем используется замена строки для замены недопустимых токенов. В моем случае сериализатор возвращает значения NaN в качестве исключения, поэтому этот метод является лучшим подходом. Если результаты обычно содержат недопустимый токен, вам лучше не использовать $.get, а вместо этого вручную извлекать результат JSON и всегда выполнять замену строки.

person user1478002    schedule 04.04.2013
comment
Умный, но не совсем надежный. Попробуйте с { "tune": "NaNaNaNaNaNaNaNa BATMAN", "score": NaN } - person JJJ; 04.04.2013
comment
и вы должны использовать jQuery. У меня нет $.get(). - person Jason S; 04.04.2013