2021年12月15日

JSON メソッド, toJSON

複雑なオブジェクトを持っており、それをネットワーク経由で送ったり、単にログ出力するために文字列に変換したいとします。

もちろん、変換された文字列にはすべての重要なプロパティを含んでいる必要があります。

私たちは、次のように変換処理を実装することができます:

let user = {
  name: "John",
  age: 30,

  toString() {
    return `{name: "${this.name}", age: ${this.age}}`;
  }
};

alert(user); // {name: "John", age: 30}

…しかし、開発の過程では、新しいプロパティが追加されたり、古いプロパティがリネーム/削除されます。このような状況で toString を毎回更新するのは面倒です。オブジェクト中のプロパティをループすることはできますが、オブジェクトが複雑で、プロパティにネストされたオブジェクトがある場合はどうなるでしょうか? それらの変換処理も実装する必要があります。 また、ネットワーク経由でオブジェクトを送信する場合には、受信側でそれらを「読み取る」ためのコードも提供する必要があります。

幸いにも、これらの処理を行うためにコードを書く必要はありません。この課題は既に解決されています。

JSON.stringify

JSON (JavaScript Object Notation) は値とオブジェクトを表現する一般的な形式です。RFC 4627 で標準として記述されています。当初はJavaScriptのために作られたものでしたが、多くの他の言語も同様に JSON を処理するライブラリを持っています。従って、クライアントが JavaScript を使い、サーバが Ruby/PHP/Java/その他 で書かれている場合に、データ交換としてJSONを使うのは簡単です。

JavaScriptは次のメソッドを提供しています:

  • JSON.stringify : オブジェクトをJSONに変換します。
  • JSON.parse : JSONをオブジェクトに変換します。

例えば、ここで student を JSON.stringify します:

let student = {
  name: 'John',
  age: 30,
  isAdmin: false,
  courses: ['html', 'css', 'js'],
  wife: null
};

let json = JSON.stringify(student);

alert(typeof json); // string です!

alert(json);
/* JSON-encoded object:
{
  "name": "John",
  "age": 30,
  "isAdmin": false,
  "courses": ["html", "css", "js"],
  "wife": null
}
*/

メソッド JSON.stringify(student) はオブジェクトを受け取り、それを文字列に変換します。

結果の json 文字列は JSONエンコードされた, シリアライズされた(serialized), 文字列化された(stringified) または 整列化された(marshalled) オブジェクトと呼ばれます。 これでネットワーク経由で送信したり、シンプルなデータストアに格納する準備ができました。

JSONエンコードされたオブジェクトは、オブジェクトリテラルと比べ、何点か重要な違いがあることに注意してください:

  • 文字列にはダブルクォートを使います。JSONにはシングルクォートやバッククォートはありません。従って 'John'"John" になります。
  • オブジェクトのプロパティ名もまたダブルクォートであり、必須です。従って age:30"age":30 になります。

JSON.stringify はプリミティブに対しても同様に適用できます。

ネイティブにサポートされるJSONタイプは次のとおりです。:

  • オブジェクト(Object) { ... }
  • 配列(Array) [ ... ]
  • プリミティブ(Primitives):
    • 文字列(strings),
    • 数値(numbers),
    • 真偽値(boolean values) true/false,
    • null.

例: