JSON文字列化/復元の基本と実践
「オブジェクト⇄文字列」を行き来する最短ルートが JSON.stringify と JSON.parse。保存・送受信・ログ・設定ファイルで頻出です。
まずは基本
// オブジェクト → JSON文字列
const obj = { name: "Aki", age: 22, tags: ["js", "web"] };
const json = JSON.stringify(obj);
console.log(json); // {"name":"Aki","age":22,"tags":["js","web"]}
// JSON文字列 → オブジェクト
const back = JSON.parse(json);
console.log(back.name); // "Aki"
JavaScript- stringify: オブジェクトを「JSON形式の文字列」にする。
- parse: JSON文字列を「JavaScriptの値(オブジェクトや配列)」に戻す。
- 用途: API送受信、localStorage保存、ログ出力、設定の読み書き。
stringifyのオプション(replacer・space)
const user = { name: "Mao", age: 22, password: "secret" };
// 1) replacerでプロパティを絞る(配列)
console.log(JSON.stringify(user, ["name", "age"]));
// {"name":"Mao","age":22}
// 2) replacerで変換(関数)
console.log(JSON.stringify(user, (key, value) =>
key === "password" ? undefined : value
));
// {"name":"Mao","age":22}
// 3) spaceで見やすく(整形)
console.log(JSON.stringify(user, null, 2));
/*
{
"name": "Mao",
"age": 22
}
*/
JavaScript- replacer(配列/関数): 含めるキーの選択や値の変換ができる。
- space(数/文字列): インデントを付けて「可読性の高い」JSONにする。
parseのオプション(reviver)
// 文字列の「特定プロパティ」を復元時に加工
const json = `{"date":"2025-12-05T00:00:00.000Z", "value": "42"}`;
const obj = JSON.parse(json, (key, value) =>
key === "date" ? new Date(value) :
key === "value" ? Number(value) :
value
);
console.log(obj.date instanceof Date); // true
console.log(obj.value === 42); // true
JavaScript- reviver: 復元時にプロパティ単位で型変換やデータ補正が可能。
よくある落とし穴と対策
- 循環参照は不可:
const a = {}; a.self = a;を stringify するとエラー。- 対策: 循環を除去(replacerでスキップ)、または専用ライブラリを検討。
- 関数/undefined/シンボルは保存されない: オブジェクトの値としては無視される(配列内では
nullにもならず欠落)。- 対策: 必要なら文字列化するルールを自前設定(replacerで変換)。
- Dateは自動ではDateに戻らない: stringifyでISO文字列になり、parseするとただの文字列。
- 対策: reviverで
new Date(value)に変換。
- 対策: reviverで
- NaN/Infinity: stringifyでは
nullになる。- 対策: replacerで別表現へ変換(例: “NaN”)。
- BigIntは非対応: 例外が発生。
- 対策: 文字列へ変換して保存→復元時にBigIntへ戻す。
- JSONの文法は厳密: 末尾カンマ、コメント、単一引用符は不可。
- 対策: JSONは「純粋なデータのみ」。コメントが欲しいなら別手段(例: 伴走ドキュメントやYAML、JSONC対応環境)。
実務テンプレート集
localStorageへ保存/復元
const settings = { theme: "dark", pageSize: 20 };
localStorage.setItem("settings", JSON.stringify(settings));
const restored = JSON.parse(localStorage.getItem("settings") || "{}");
JavaScript- ポイント: 取得時に
|| "{}"でガードすると安全。
try/catchで安全にパース
function safeParse(json, reviver) {
try {
return JSON.parse(json, reviver);
} catch (e) {
return null; // 失敗時はnullやデフォルト値
}
}
console.log(safeParse('{"ok":1}')); // { ok: 1 }
console.log(safeParse('{"bad": }')); // null
JavaScript- ポイント: 外部入力のパースは必ず例外対策。
セキュリティ情報を除外してログ出力
function sanitizeLog(obj) {
return JSON.stringify(obj, (k, v) =>
["password", "token", "secret"].includes(k) ? "***" : v
);
}
console.log(sanitizeLog({ user:"Aki", token:"abc" }));
// {"user":"Aki","token":"***"}
JavaScript- ポイント: replacer関数で機密情報をマスク。
人間向けに整形(pretty print)
function pretty(obj) {
return JSON.stringify(obj, null, 2);
}
console.log(pretty({ a:1, b:{ c:[1,2,3] } }));
JavaScript- ポイント: デバッグ・レビューでは整形出力が圧倒的に読みやすい。
深いコピー(注意点あり)
const src = { a: 1, b: { c: 2 } };
const copy = JSON.parse(JSON.stringify(src));
JavaScript- 注意: 関数・Date・Map/Setなどは失われる。純粋データに限定して使う。
練習問題(手を動かして覚える)
- 1. パスワードを除外して文字列化
const user = { name: "Ren", pass: "xxx", role: "admin" };
console.log(JSON.stringify(user, (k, v) => k === "pass" ? undefined : v));
JavaScript- 2. Date文字列をDateへ復元
const json = `{"when":"2025-12-05T09:00:00.000Z"}`;
const obj = JSON.parse(json, (k, v) => k === "when" ? new Date(v) : v);
console.log(obj.when.toISOString());
JavaScript- 3. 整形して読みやすく出力
console.log(JSON.stringify({ a:1, arr:[1,2,3], nested:{ x:10 } }, null, 2));
JavaScript直感的な指針
- 送受信・保存: stringifyで文字列化、parseで復元。
- 型の維持: Dateなどはreviverで戻す。非対応型は事前に設計。
- 安全第一: 外部入力は必ずtry/catch。機密はreplacerでマスク。
- 読みやすく: spaceで整形、ログや設定に最適。
