JSON と JavaScript オブジェクトの違い
JSON と JavaScript オブジェクトは見た目が似ていますが、いくつかの重要な違いがあります。これらの違いを理解することで、データの変換時に起こりうる問題を回避できます。
構文の違い
JavaScript オブジェクトでは柔軟な記法が許されていますが、JSON はより厳格です。
| 項目 | JavaScript オブジェクト | JSON |
|---|---|---|
| キーのクォート | 省略可能 | 必須(ダブルクォート) |
| 文字列のクォート | シングル・ダブル両方可 | ダブルクォートのみ |
| 末尾のカンマ | 許容される | 禁止 |
// JavaScript オブジェクト(有効)
const jsObj = {
name: '田中',
age: 25,
};
// JSON 文字列(有効)
const jsonStr = '{"name": "田中", "age": 25}';データ型の違い
JavaScript オブジェクトはあらゆる JavaScript の値を保持できますが、JSON で表現できるのは限られた型のみです。
JavaScript オブジェクトで使える値
文字列、数値、真偽値、null、undefined、関数、Symbol、Date、正規表現、Map、Set など、すべての JavaScript 値を格納できます。
JSON で使える値
文字列、数値、真偽値、null、オブジェクト、配列の6種類のみです。関数や undefined は表現できません。
変換時の挙動
JSON.stringify() で JavaScript オブジェクトを JSON に変換する際、一部の値は失われます。
const original = {
name: "田中",
greet: function() { return "Hello"; },
created: new Date(),
value: undefined,
sym: Symbol('test')
};
const json = JSON.stringify(original);
console.log(json);
// '{"name":"田中","created":"2024-01-01T00:00:00.000Z"}'関数、undefined、Symbol は完全に消え、Date は文字列に変換されています。JSON.parse() で戻しても、元の Date オブジェクトにはなりません。
const parsed = JSON.parse(json);
console.log(typeof parsed.created); // "string"(Date ではない)参照とコピー
JavaScript オブジェクトは参照型ですが、JSON 変換を経由すると完全に新しいオブジェクトが作られます。
const obj = { a: 1, b: { c: 2 } };
const copy = JSON.parse(JSON.stringify(obj));
copy.b.c = 999;
console.log(obj.b.c); // 2(元のオブジェクトは影響を受けない)この特性を利用してディープコピーを作ることもできますが、上記の型制限があるため万能ではありません。JSON に変換できない値を含むオブジェクトのコピーには、structuredClone() などを使用するのが適切です。