JSON とは何か
JSON は「データを文字列で表すための軽量フォーマット」です。JavaScript のオブジェクトに“似ている”けれど、JSON はあくまで文字列。送受信・保存に向いており、プログラム内で使うには「文字列 ⇄ オブジェクト」の変換が必要になります。ここが重要です:JSON にできるのは、数値・文字列・真偽値・null・配列・“素のオブジェクト”だけ。関数、undefined、Symbol、Date、Map/Set などはそのままでは表現できません。
JSON.stringify とは(オブジェクト → JSON文字列)
基本の使い方と結果
const obj = { id: 1, name: "Alice", ok: true };
const json = JSON.stringify(obj);
console.log(json); // '{"id":1,"name":"Alice","ok":true}'
JavaScriptJavaScript の値を“JSON文字列”に変換します。これをファイル保存、HTTP 送信、ローカルストレージなどに使います。
フォーマット整形(インデント)
JSON.stringify(obj, null, 2); // 第3引数で見やすく整形(2スペース)
JavaScript読みやすいログや設定ファイルを出力するときに便利です。
replacer でフィルタ・変換
const replacer = (key, value) => (key === "password" ? undefined : value);
JSON.stringify({ id:1, password:"secret" }, replacer);
// '{"id":1}'
JavaScript含めたくないフィールドを落としたり、値を変換できます。
できない・落ちるもの(ここが重要)
- 関数、undefined、Symbol は“オブジェクトのプロパティにあると”落ちます(フィールド自体が削除される)。配列内では null や省略になります。
- 循環参照は TypeError(自分を指す構造)。深いコピー目的で stringify を使うときは循環に注意。
- BigInt は未対応。含まれると例外になります。
const a = {}; a.self = a;
JSON.stringify(a); // TypeError: Converting circular structure to JSON
JavaScriptJSON.parse とは(JSON文字列 → オブジェクト)
基本の使い方
const json = '{"id":1,"name":"Alice","ok":true}';
const obj = JSON.parse(json);
console.log(obj.name); // "Alice"
JavaScript受け取った JSON文字列を“使えるデータ”に戻します。
reviver で変換・復元
const json = '{"date":"2025-12-16T09:00:00.000Z"}';
const obj = JSON.parse(json, (key, value) => {
return key === "date" ? new Date(value) : value;
});
obj.date instanceof Date; // true(Dateとして復元)
JavaScript文字列で届いた値を型へ復元できます。特に Date は標準では文字列のままなので reviver が有効です。
例外対策(必ず try/catch)
try {
const data = JSON.parse(payload);
} catch (e) {
// 不正なJSON(欠落したカンマや引用符)に備える
}
JavaScript外部入力は常に構文エラーの可能性があるため、パースはガード必須です。
stringify/parse の“型の壁”(深掘り)
JSON にできない(失われる)情報
- 関数、undefined、Symbol、Map/Set、Date(文字列化されるだけ)、正規表現(オブジェクト化されない)。
- プロトタイプやクラスのメソッドは消える。戻すと“素のオブジェクト”になります。
class User { constructor(name){ this.name = name; } greet(){ return "hi"; } }
const u = new User("Alice");
const back = JSON.parse(JSON.stringify(u));
typeof back.greet; // "undefined"(メソッドは消える)
JavaScript数値と文字列の取り違いに注意
JSON は数値・文字列の区別を保つが、日付やIDを“文字列で持つか数値で持つか”は設計次第。復元時に型チェックを入れると安全です。
浮動小数・精度の理解
JSON の数値は二進浮動小数。通貨など精度が重要なら文字列で保存し、パース後に専用ライブラリで扱うのが現実的です。
深いコピーとして使うときの注意
JSON 経由のコピー(純粋データ限定)
const pure = { a: 1, b: "x", c: [2, 3], d: { e: 4 } };
const deep = JSON.parse(JSON.stringify(pure));
JavaScript“純粋データ”なら深いコピーになります。ただし次の制限があります。
- 関数・undefined・Symbol は落ちる。
- Date/Map/Set/RegExp/TypedArray は失われる(文字列・プレーン化)。
- 循環参照は例外。
型が混ざるなら structuredClone を使うのが安全です。
実務の定番パターン(整形・安全化・互換)
送信前のサニタイズ(機密の除去)
function sanitize(user) {
return JSON.stringify(user, (k, v) => (k === "password" || k === "token") ? undefined : v);
}
JavaScript不要フィールドを落としてから送る。
ログ・設定ファイルの整形出力
const pretty = JSON.stringify(config, null, 2); // インデント付き
JavaScript人が読むファイルは整形出力で保守性を高める。
受信後の型復元(reviver)
const revive = (json) => JSON.parse(json, (k, v) => k.endsWith("At") ? new Date(v) : v);
JavaScript日時フィールドを自動で Date に戻す。
セキュリティと安定運用(重要ポイントの深掘り)
JSON と XSS/コード実行の線引き
JSON は“文字列”であり、eval してはいけません。必ず JSON.parse を使うこと。HTML に埋め込むときはエスケープを徹底します。
入力バリデーション
“JSON であること”と“期待スキーマに合うこと”は別問題。パース後に必須フィールドの存在・型を検証しましょう。
function validateUser(u) {
return u && typeof u.id === "number" && typeof u.name === "string";
}
JavaScript文字コードとエスケープ
JSON は UTF-8 が一般的。stringify は必要な文字を自動エスケープしますが、改行・制御文字の扱いに注意。巨大文字列は分割・圧縮も検討します。
まとめ
JSON.stringify は「オブジェクトをJSON文字列へ」、JSON.parse は「JSON文字列をオブジェクトへ」変換します。ここが重要です:JSON にできる型は限定的で、関数・undefined・Symbol・複雑な型は失われます。深いコピー目的での JSON 経由は“純粋データ”に限り安全。送受信では整形(第3引数)・replacer でのフィルタ・reviver での型復元を使いこなし、外部入力は必ず try/catch とスキーマ検証で守る。これらを押さえれば、初心者でも安心してデータを“文字列として運ぶ/保存する”設計ができます。
