Могут ли NaN или Infinity появляться в JSON
Главное: В JSON только десятичные числовые литералы. JSON.stringify превращает NaN и Infinity в null без предупреждения, из-за чего «числовое поле иногда null» продолжает появляться в продакшене.

Главное: JSON не может представлять NaN или Infinity — JSON.stringify молча превращает оба в null — поэтому кодируйте состояние явно через null плюс поле причины или через документированное строковое значение.
JSON.stringify({ ratio: NaN, limit: Infinity });
// '{"ratio":null,"limit":null}'
Без ошибки, без предупреждения. Два числа становятся null.
Что допускает грамматика
number = [ minus ] int [ frac ] [ exp ]
Только десятичные. NaN и Infinity — это сигнальные значения IEEE 754, а не литералы. Записанные в JSON, они являются недопустимыми идентификаторами, и поскольку их семантика сравнения различается между языками, спецификация исключает их, а не выбирает представление.
Что делает каждый язык вместо этого
| Язык | Поведение |
|---|---|
JavaScript JSON.stringify |
Молча выдаёт null |
Python json.dumps |
По умолчанию выдаёт NaN (нестандартно); выбрасывает при allow_nan=False |
Go encoding/json |
Возвращает unsupported value: NaN |
| Java Jackson | По умолчанию выдаёт строку "NaN" |
Четыре поведения для одного значения. Когда кросс-языковой API показывает числовое поле, которое периодически равно null, проверьте этот слой первым.
Что делать вместо этого
Документированные строки. "NaN", "Infinity" с примечанием о типе. Стоит каждому потребителю явной проверки.
null плюс поле статуса. Лучше: {"avgLatency": null, "avgLatencyStatus": "no-sample"}. Причина путешествует вместе со значением.
Переосмыслите единицу. Большинство результатов Infinity происходит от деления на нулевое число выборок. Возврат null и отображение «данных пока нет» обычно лучше соответствует бизнес-истине, чем бесконечное число.
Связанные ловушки
- Библиотеки графиков разрывают линию на
null— подтвердите, что вы этого хотите JSON.stringifyтакже полностью отбрасываетundefined, функции и символы; эти ключи исчезают, а не становятсяnull- Значение
allow_nan=Trueв Python по умолчанию даёт вывод, которыйJSON.parseотвергает