シリアライズ化が必要なのは、たとえば次の場面
- データをバイト列で表現したいとき
- 設定にオブジェクトを保存したいとき
Javaとかには
Serializable インターフェースがあって楽みたいですが、
名前が似ているだけの JavaScript にはそんな便利なものは存在していません。
そこで自分への忘備録も兼ね、
JavaScriptでデータをシリアライズ(直列化)する方法 をメモ(?)しておきます。
注意事項 : バイナリデータの直列化には未対応なやり方
このページの目次
シリアライズってそもそも何?ココでの定義
まず シリアライズ とは何かについて説明
Wikipediaの説明によると、次の2通りの意味があるみたいです。
コンピュータプログラミングにおいて、シリアライズ (serialize)、もしくはシリアル化 という用語は、次のような異なる2つの意味を有する。
1. ある一つの資源を、複数の主体が利用しようとするときに、それを調整(同期)して、一つの時点では一つの主体だけがそれを利用するようにすること。この意味では逐次化という訳語が用いられる。対義語は並列化である。
2. ある環境に存在しているオブジェクト(のネットワーク(グラフ)構造)をバイト列に変換すること。この意味では直列化という訳語が用いられる。同義語にMarshalling (マーシャリング)がある。対義語は直列化復元ないしデシリアライズである。シリアライズの名詞形はシリアライゼーション (serialization)である。
引用元 : シリアライズ - Wikipedia
シリアライズ、シリアライズというけど、実は2つの意味があります。
ここでのシリアライズは2番目の方
つまり何らかのデータ(配列、オブジェクト、クラスのインスタンス)を1つのバイト配列とかXML形式とかJSON形式に変換することですね。
それで直列化することで次の利点が享受できます。
- データをファイル保存できる
- ネットワークで送信もできる
- データの復元も簡単
流れとしては 1.データをシリアライズ化 => 2.必要なところに渡す => 3、データを復元(デシリアライズ) するという感じです。
JSONを使ってクラスをシリアライズ化するやり方
今説明したようにシリアライズの方法も色々あります。
ここでは 次の方法でシリアライズ(とその逆) を試してみました。
1.まずはデータをシリアライズ化する方法
これには JSON.stringify メソッドを使うのが簡単
その名の通り、あるオブジェクトを文字列化するためのメソッド です。
例えば直列化したいデータ(クラス)として次があるとしましょう。
▼ 座標管理するだけの "車輪の再発明" みたいなクラス
1 2 3 4 5 6 7 |
class Vector3{ constructor(x, y, z){ this.x = x; this.y = y; this.z = z; } } |
もし
[1, 2] とかの配列、
{x: 123} みたいなオブジェクトなら、
JSON.stringify にそのまま渡せばすぐシリアライズ化できるんですが・・・
でもクラスの場合は少しだけシリアライズ化に工夫が必要になります。
実際に上のクラスをシリアライズ化するコードは次の通り
▼ Vector3 をシリアライズ化(JSON化)する関数
1 2 3 4 5 6 7 8 9 10 11 |
function vec3ToJson(vec3){ if(! vec3 instanceof Vector3){ return ''; } return JSON.stringify({ x: vec3.x, y: vec3.y, z: vec3.z }); } |
このコードのように、クラスのインスタンスのみをシリアライズ化してJSON化してます。
JavaScriptでは クラスインスタンスを直接シリアライズ化できない ので、こういう工夫をしないとダメ
▼ 実際にシリアライズ化してみた
1 2 3 4 5 6 |
var json = vec3ToJson( new Vector3( 1.5, -2.5, 3.5 ) ) console.log(json); |
▼ このコードの出力結果
1 |
{"x":1.5,"y":-2.5,"z":3.5} |
こういう風に方法さえキッチリしとけば、どんなクラスでも文字列化可能です。
2.シリアライズ化したデータを元に復元してみる
シリアライズ化したら当然その逆の処理も用意しとかないといけません。
それには JSON.parse メソッドを使うのがベスト
これは JSON文字列元のオブジェクト・配列に戻すメソッド です。
ちなみに元に戻すのはデシリアライズ化(直列化)という呼び方
例えば先ほどのクラスなら・・・デシリアライズするコードは次の通り
▼ こういう関数を作ってみる
1 2 3 4 5 6 7 8 9 10 11 12 13 |
function jsonToVec3(json){ var vec3 = null; try{ var data = JSON.parse(json); vec3 = new Vector3( data.x, data.y, data.z ); }catch(e){ /// エラー時の処理 console.e('Failed to parse json'); } return vec3; } |
JSON文字列を受け取り、オブジェクトに戻してクラスインスタンスを作成するという関数
▼ このクラスで先ほどのJSONを復元してみた
1 2 3 4 |
/// シリアライズ化されたもの var json = '{"x":1.5,"y":-2.5,"z":3.5}'; var vec3 = jsonToVec3(json); console.log(vec3); |
▼ このコードの出力結果
1 |
Vector3 { x: 1.5, y: -2.5, z: 3.5 } |
うん、ちゃんと元のクラスインスタンスに復元できてます。
シリアライズ化とその逆のまとめ
シリアライズ化するなら次の2つのメソッドを上手く使えばOK
- JSON.stringify
クラスインスタンス・オブジェクトをシリアライズ化するのに使える。ただしクラスの場合はJSON化するのに工夫が必要
- JSON.parse
シリアライズ化したデータを元に戻すのに使える。ただしJSON化したときと全く真逆のことをしないと整合性が取れない
もし「もっといい方法あるけど・・・」という方は コメント欄 で教えてください。
以上、JavaScriptでのシリアライズ化 or その逆のやり方でした。ではまた(^_^)/~