JSON に NaN や Infinity は現れるか
要点:JSON には十進数リテラルしかありません。JSON.stringify は NaN と Infinity を警告なしに null にするので、「数値フィールドが時々 null」という現象が本番で起き続けます。
初級約 3 分で読めます2026-10-30 公開2026-10-30 更新

要点: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にならず消えます。- Python の既定
allow_nan=TrueはJSON.parseが拒否する出力を生みます。