JSONの末尾カンマ問題
標準JSONで末尾カンマが無効である理由、それを許容するツール、JSONドキュメントでこのよくある構文エラーを回避する方法を解説します。
詳細な説明
末尾カンマ(ダングリングカンマとも呼ばれる)とは、arrayの最後の要素やobjectの最後のkey-valueペアの後に置かれたカンマのことです。多くのプログラミング言語やデータ形式では末尾カンマが許可されていますが、標準JSONでは厳格に禁止されています。これはJSON解析エラーの最も頻繁な原因の一つです。
末尾カンマが無効な理由:
RFC 8259およびECMA-404で定義されたJSON文法では、arrayの値やobjectのメンバーはカンマで区切られると規定されています。最後の要素の後のカンマは、その後にもう一つの要素が続くことを暗示しますが、実際には存在しません。これによりドキュメントは文法的に無効になります。仕様はすべてのパーサーとプログラミング言語間で最大限の相互運用性を確保するために、意図的に厳格に設計されています。
実際の問題:
次のobjectを考えてみましょう:
{
"name": "Alice",
"age": 30,
}
30 の後のカンマにより、これは無効なJSONになります。この文字列に対して JSON.parse() を実行すると、SyntaxError: Unexpected token } in JSON がスローされます。このエラーメッセージは、実際の問題がカンマであるにもかかわらず閉じブレースを指すため、混乱を招くことがあります。
開発者が末尾カンマを付け続ける理由:
JavaScriptでは末尾カンマは有効であり、人気のスタイルガイド(Airbnb、Prettierのデフォルト)でも推奨されています。これはgitの差分がクリーンになるためです。新しいプロパティを追加する際に、前の行にカンマを追加するための変更が不要になります。JavaScriptオブジェクトの記述に慣れた開発者は、JSONがより厳格な形式であることを忘れて、自然に末尾カンマを付けてしまいます。
開発者がよくやるミス:
習慣的に末尾カンマを付けてしまうこと以外に、ループ内で文字列連結によりJSONを生成し、最後の要素を含む各アイテムの後にカンマを追加してしまうことがよくあります。より良いアプローチは、JSON.stringify() や使用言語の同等機能を使うことで、構文的に正しい出力が得られます。もうひとつのミスは、JavaScriptファイルは自動修正するがJSONファイルは対象外のリンターを使用し、末尾カンマがそのまま残ることです。
末尾カンマを許容するツール:
JSONCパーサー(VS CodeやTypeScriptで使用)は末尾カンマを受け入れます。JSON5も許可します。Python(json5 パッケージ)やGo(カスタムオプション付きの json.Decoder)など、一部の寛容なパーサーも処理できます。ただし、データ交換時にこの動作に依存すべきではありません。
ベストプラクティス:
厳密なJSONパーサーでパースする前に末尾カンマを除去してください。末尾カンマを自動的にフラグするJSON対応のエディタやリンターを使用しましょう。プログラムでJSONを生成する際は、文字列連結ではなく、使用言語の組み込みJSONシリアライザーを必ず使用してください。
ユースケース
開発者がJavaScriptオブジェクト構文から末尾カンマ付きでコピーした後、パースに失敗するJSON設定ファイルをデバッグする。