JavaScript | 配列・オブジェクト:オブジェクト操作 – JSON.parse / stringify

JavaScript JavaScript
スポンサーリンク

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}'
JavaScript

JavaScript の値を“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
JavaScript

JSON.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 とスキーマ検証で守る。これらを押さえれば、初心者でも安心してデータを“文字列として運ぶ/保存する”設計ができます。

タイトルとURLをコピーしました