なぜDate.prototype.toJSONが重要なのか
Web開発において、フロントエンドからサーバーへデータを送信する際、JSON形式への変換は避けて通れません。しかし、JavaScriptのDateオブジェクトをそのままJSON化しようとすると、期待通りの形式にならず、バックエンド側で解析エラーが発生することがあります。この課題を解決するのが Date.prototype.toJSON です。このメソッドの挙動を正しく理解することで、日付データ通信のトラブルを未然に防ぐことができます。
基礎知識:toJSONとは何か
JavaScriptの JSON.stringify() メソッドは、オブジェクトをJSON文字列に変換する際に、対象のオブジェクト内に toJSON メソッドが存在するかを確認します。もし存在する場合、JSON.stringifyはオブジェクトそのものではなく、toJSONメソッドが返した値をJSON化します。
Dateオブジェクトには標準でこのメソッドが組み込まれており、自動的に ISO 8601形式(例: “2023-10-27T10:00:00.000Z”) の文字列へ変換されます。
実装と解決策
多くの場合、デフォルトの挙動で十分ですが、APIの仕様によっては「YYYY-MM-DD」形式のみを要求されるなど、特定のフォーマットが必要な場合があります。その際は、DateオブジェクトのtoJSONをオーバーライド(上書き)することで、グローバルな挙動を制御できます。
サンプルプログラム
以下のコードは、標準の動作確認と、独自のフォーマットにカスタマイズする例です。
// 1. 標準の挙動確認
const now = new Date();
console.log(JSON.stringify({ date: now }));
// 出力例: {"date":"2023-10-27T10:00:00.000Z"} (ISO 8601形式)
// 2. 特定のフォーマットにカスタマイズしたい場合
Date.prototype.toJSON = function() {
// YYYY-MM-DD形式に変換する関数
const year = this.getFullYear();
const month = String(this.getMonth() + 1).padStart(2, '0');
const day = String(this.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
};
const customDate = new Date();
console.log(JSON.stringify({ date: customDate }));
// 出力例: {"date":"2023-10-27"} (カスタマイズされた形式)
応用・注意点
現場での開発において注意すべき点は、Date.prototypeへの直接的なプロトタイプ拡張です。上記のようにグローバルなプロトタイプを書き換えると、プロジェクト内のすべてのDateオブジェクトに影響が及びます。
特定のAPIでのみ形式を変えたい場合は、プロトタイプを直接編集するのではなく、変換用のユーティリティ関数を作成して、JSON.stringifyに渡す前に明示的に変換するアプローチを強く推奨します。グローバル汚染を避けることが、大規模開発におけるバグの温床を断つ鍵となります。