gorogoronyan FC2

JavaScript: JSON シリアライズ

概略

データ保存のときに JSON を使うと、 複雑な構造を持つデータのデータファイルの読み書きも容易になります。

◎ 複雑な構造を持つデータの例

・単純な 1次元リストや 2次元配列ではないデータ。
  単純な行単位のテキストや CSV,TSV などの 2次元テキストでは
 扱えないデータ。

1)データオブジェクトの中にリストやマップ(キー:値のデータ)を
 多く含むデータ。
2)ツリー状の構造を持つデータ

など

JSON

JSON は JavaScript のオブジェクト (Object) をデータファイルなどに保存したり データファイルを読んだりするときに便利です。 JSON の中身はテキストで JavaScript のコードになっています。
MDN: Object
MDN: JSON データの操作

JSON では簡単な記述でオブジェクトをテキスト化できます

JSON ではたった 1行のコードで読み書きできます。

//データのオブジェクトを作る。
const data1 = {
	name: "名前",
	key1: "文字列",  //値が文字列 (string)
	key2: 123,       //値が数値 (Number)
	key3: true       //値が論理型 (boolean)
};

//data1 を JSON テキストに変換する (シリアライズ)。
const json = JSON.stringify(data1);

//json はローカルファイルに保存したり、サーバーにアップロードしたりできる。
...(省略)

//JSON テキストをオブジェクトに戻す (デシリアライズ)。
const data2 = JSON.parse(json);

JSON は専用の書式をもつデータよりも便利です

専用の書式 (フォーマット) を持つデータファイルでは、 データを保存するときに指定された形式のデータに変換したり、 データを読むときに複雑なパースをしたりする処理が必要になります。 このような処理は非常に手間がかかり、プログラムコードも巨大になりやすいです。 JSON で読み書きするとこのような処理がとても簡素になります。

◎ 専用の書式を持つデータの例 : 囲碁の SGF データ
(;CA[utf-8]AB[pr][rp][rq]AW[ro][qo][qp][qq][oq][or]LB[pq:A][qp:B]N[5k]AP[MultiGo:4.4.4]
AB[qr]MULTIGOGM[0]
(;B[sr]C[正解]
(;W[rs];B[sp]
(;W[rr];B[qs]LB[pq:A]C[Aが空いてるので取れる])
(;W[ps];B[qs]C[空いているのでアタリにならない。]))
...

・専用の書式を持つデータファイルを読み書きするプログラムは、
 大規模で複雑になりやすい。
  SGF ファイルの処理
・上のようなデータも JSON で簡単に読み書きすることができる。

また、JSON は XML と比べても文字列型、数値型、論理型、 配列などの区別ができるので便利です。
データフォーマット: JSON と XML の比較

JSON の使用例

サンプル

JSON 化できないオブジェクトに注意

オブジェクトの内容によっては JSON 化できないオブジェクトがあります。

◎例
const json = JSON.stringify(obj);
のときにエラーが出る obj もある。

JSON 化できないオブジェクトの例

・HTML要素 (p, div など各種 HTMLElement)
・ノードのリンクがループしていたり、クモの巣状につながっていたり
 する場合。

データファイルで読み書きするオブジェクトは、 JSON シリアライズできない制限にひっかからないように注意します。 データオブジェクトにシリアライズできない変数がついてる場合は、 シリアライズのときに保存したい変数だけを取り出す前処理をしたり、 デシリアライズのときにアプリケーション用に初期化したりする処理を追加します。

この話は、
1) ループを含むツリー構造を持つデータオブジェクト
2) クモの巣状のリンク構造を持つデータオブジェクト
などで出てきます。
ツリー構造のデータを扱う (2)
ツリー構造のデータを扱う (4)

# の private プロパティは JSON 出力されません

class 内のプロパティ名の先頭に # を付けると private のフィールドになります。 これと set/get を組み合わせて Java や C# でもよく出てくる setter/getter 付きのプロパティを作ることができます。

ただし、# の private プロパティには難点があって、 JSON 出力のときに # のプロパティは JSON 出力されません。

Array に付けたプロパティは JSON 出力されません

関連

inserted by FC2 system