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);
- TestJS_json_object01.html
連想配列 (Object) をJSON にする。JSON を Object に戻す。
連想配列 Object (1) - TestJS_json_array01.html
配列 Array も JSON で読み書きできます。
配列: JSON で読み書きする - TestJS_json_format01.html
JSON の文字列を読み、インデントの整形をして再び JSON 出力する。
ツールサンプル (1)
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 の使用例
- ツリー構造のデータを扱う (2)
ツリー構造を持つデータを JSON で読み書きする例。 - Node.js: テキストの処理 (1)
Node.js のコマンドライン処理。ファイルリストを JSON で保存する例。
サンプル
- TestJS_textarea_read_xy01.html
(x, y) の座標データを読み取って 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 出力されません
- TestJS_json_array_property01.html
Array にプロパティを付け JSON 出力するサンプル。
配列 Array (2)
関連
- JavaScript はじめの一歩 (2)
- JavaScript: 配列 Array (1)
- JavaScript: 配列 Array (2)
- JavaScript: 連想配列 Object (1)
- JavaScript: 連想配列 Object (2)
- JavaScript: テキストデータを読んで処理
- JavaScript: ファイル処理 FileAPI
- JavaScript: ツリー構造のデータを扱う (1)
- JavaScript: ツリー構造のデータを扱う (2)
- JavaScript: ツリー構造のデータを扱う (4)
- データフォーマットの話
- データフォーマット: JSON と XML の比較
- C#: XML シリアライズ