javascript JSONについて理解を深める

#JSON

##きっかけ
暗号化を学ぶにあたって、データのやり取りに関する知識が必要になったのが始まり。

javascriptでデータのやり取りに困っていたところ、JSONという様々なデータのやり取りに便利な言語の存在を知ったため。

##JSONとは
**JavaScript Object Notation**の略で、
JSONは、構造化したデータを表すための**データ記述言語**

名前に、「JavaScript」とついているのは、書式をJavaScriptに従っただけなので、JavaScript専用というわけではない。

JavaScript以外のプログラミング言語にも対応している。
（Java、C#、PHP、Python、C++など）

特に、 **Ajax** や REST API などで使用されている。

### JSONの基本構造
{} の中に、ダブルクォーテーション(")で囲んだ変数名と値をカンマ(:)で区切り、下記の様に記述。

```js:json.js
//JSONの基本構造
{
  //左がプロパティ(key)で右が値(value)
  "name": "ランパート",
  "age": 21,
  "ult": "ミニガン「シーラ」"
}
```

※文字コードはUTF-8

##JSONはデータ構造を表すのに使われる
データを構造で表す点では、**XML**と似ているが、
テキストにタグを付けることでデータを表現するXMLと違って、
JSONでは、データを階層的に並べることで構造を表現している。

JSONを利用することで、データを構造的に表現できるだけでなく、

データを構造化することで、
WebブラウザとWebサーバー間とのデータのやり取りに扱いやすくなる。

※**XML**・・・自由な形式で柔軟に構造化された文書を作ることができるHTMLと同様のマークアップ言語。

###JSONとXMLの違い
####・XML

1. データとして文字列しか表すことができない。
 
1. テキストの任意の場所にタグ付けできる

1. 全ての情報にタグ付けする必要があるため、その分データサイズが大きくなる

####・JSON

1. データとして文字列以外に、数値や空を意味するデータなども扱うことができる
 
1. タグによるマーク付けがないため、人間には読みにくいデータとなる。

1. データを括弧で囲んで構造を表すので、データファイルは比較的に小さい

どちらもメリット・デメリットは存在するが、
タグ名などでデータサイズが大きくなりがちなXMLよりもJSONの方がデータが小さく、
その分ネットワークの転送速度が速くなる。

共通データ記述言語としてXMLが利用されてきたが、
JavaScriptがよく利用されるWebの世界では選択されやすいデータ形式である。

###JavaScriptでJSONを利用する利点

1. JavaScriptの書式に従っているため、JavaScriptで書かれたプログラムではJSONをそのままJavaScriptとして読み込むことができる。

1. XMLのようにDOMを利用する必要がない。

1. 文字列以外のデータを扱う場合にも利用できる。

##JSONの"型"について
JSON では下記の型を使用することができます。

1. 文字列 ("...")
ダブルクォーテーション(")で囲んだ文字列を指定します。

2. 数値 (123, 12.3, 1.23e4 など)
123, 12.3, 1.23e3 などの数値を指定します。

3. ヌル値 (null)
値が無いことを示すヌル値を null で指定します。null はすべて小文字で指定します。

4. 真偽値 (true, false)
真偽を true または false で指定します。true や false はすべて小文字で指定します。

5. オブジェクト ({ ... })
オブジェクトを {...} で指定します。オブジェクトは階層構造を持つことができます。

6. 配列 ([...])
配列を [...] で指定します。配列要素には、文字列、数値、ヌル値、真偽値、オブジェクト、配列すべてを使用することができます。

##JSONの使い方
一般的なJSONの生成方法からデータの追加や削除をまとめます。

###JSONデータの作成

```js:json.js
var json = {
  "name": "レイス",
  "age": "32",
  "ult": "ディメンションリフト"
}
```

この例では、jsonという変数の中に、
3つのプロパティと値がペアになったJSONデータを作成しています。

###配列構造のデータも作成できる
3人分の情報をデータとして扱いたい場合

```js:json.js
var jsons = [
  {
    "name": "バンガロール",
    "age": "38",
    "ult": "ローリングサンダー"
  },
  {
    "name": "ライフライン",
    "age": "24",
    "ult": "ケアパッケージ"
  },
  {
    "name": "パスファインダー",
    "ult": "ジップラインガン"
  }
]
```

これらのデータを拡張子.jsonで保存すれば、
他の言語でもJSONデータとして扱えるようになる。

##データの参照
次に、作成したJSONデータをプログラムで利用するために参照方法についてです。

上記で作成したJSONデータは、一般的なオブジェクトと同じように指定可能です。

`変数名.プロパティ名`で**値**を取得できます。

```js:json.js
//単一のデータの場合
console.log(json.name);

//配列データの場合
console.log(jsons[0].name);
console.log(jsons[1].age);
console.log(jsons[2].age);
```

```console:console
レイス
バンガロール
24
undefined
```

この例では、JSONデータが格納されている変数名に「.（ドット）」を繋げることでプロパティにアクセスしています。

配列構造のJSONも「jsons[1].name」とすれば取得することができます。

##データの操作
JSONデータをプログラミングするのに便利な追加・削除の方法について学びます。

###JSONデータを追加する
普通のオブジェクト構造にデータを追加する方法と同じです。

```js:json.js
var json = {
  "name": "ジブラルタル",
  "age": "30",
  "ult": "防衛爆撃"
}
```

このようなJSONデータに、新しく「ability」というプロパティと値を追加したい場合

```js:json.js
json.ability = "プロテクトドーム"
```

これで、JSONデータへ「"ability": "プロテクトドーム"」という項目が新規に追加されたことになります。

###配列データに追加する

また、配列構造をしているJSONについては「push」を活用することで追加が行えます。

これは新しくデータを追加する場合

```js:json.js
jsons.push({name: 'ブラッドハウンド'})
```

既存のデータにプロパティと値をだけを追加したい場合は

```js.json.js
jsons[1].ability = 'D.O.C.ヒールドローン';
```

この例は、1番目に登録されているJSONデータの中に「ability」というプロパティを新規に追加するという意味になります。

###データを削除する方法
最も簡単な方法としては、オブジェクトデータを削除できる「delete」演算子を使う方法。

```js:json.js
var json = {
    "name": "ミラージュ",
    "age": "30",
    "ult": "パーティライフ"
}
 
delete json.ult;
 
console.log( json );
```

```console:console
{"name":"ミラージュ","age":"30"}
```

##JSONデータをエンコードする方法
オブジェクトデータをJSONデータに変換したい場合には
様々な値をJSONデータにすることができる `JSON.stringify()`メソッドを使う。

()内に、JSON化したいデータを指定する。

```js:json.js
var obj = {
    name: 'コースティック',
    age: 48,
    ability: 'Noxガストラップ'
}

var json = JSON.stringify(obj);

console.log(json);
```

```console:console
{"name":"コースティック","age":48,"ability":"Noxガストラップ"}
```

オブジェクトデータからJSONデータに変換したときに
consoleを見ると各プロパティが""で囲まれている。

ちなみに、プロパティの値がundefinedの場合には、JSON変換時に省略されてしまう。

###配列データをエンコードする方法
例として次のような配列データを用意

```js:json.js
var legends = [
  {
    name: 'オクタン',
    age: 24
  },
  {
    name: 'ワットソン',
    age: 22
  },
  {
    name: 'クリプト',
    age: 31
  }
];
```
この場合にもオブジェクトをJSON化する手順と同様に行う。

```js:json.js
var json = JSON.stringify(legends);

console.log(json);
```
配列legendsをJSON.string()の引数に指定。

```console:console
{"name": "オクタン","age": 24},{"name": "ワットソン","age": 22},{"name": "クリプト","age": 31}
```
配列データの各オブジェクトをJSON化できました。


##JSONデータをオブジェクトにデコード(decode)する方法
JSONデータは単なるテキストデータであり、文字列でもあるので、JavaScriptで扱えるような形式に変換する必要があるのでその方法について

プログラムで利用しやすい形式に変換する`JSON.parse() `メソッド

```js:json.js
var obj = {
    name: 'ローバ',
    age: 34,
    ability: '盗賊の相棒'
}

var json = JSON.stringify(obj);

console.log(json.name);
```
```console:console
undefined
```

この例では、オブジェクトデータをJSONデータに変換した後に、
nameプロパティを呼び出したのだが、consoleには「undefined」と表示されてしまう。

文字列データのJSONにオブジェクトと同様なアクセスすることはできないとのこと。

その対処法として**デコード**が用いられる。
JSONデータをもう一度オブジェクトデータ形式に変換して、JavaScriptで扱えるようにする。

```js:json.js
var obj = {
    name: 'ローバ',
    age: 34,
    ability: '盗賊の相棒'
}

var json = JSON.stringify(obj);

//追加
//JSONをオブジェクトデータの形式に変換
json = JSON.parse(json);

console.log(json.name);
```
```console:console
ローバ
```

このように「json.name」の値を表示してくれるようになります。

JSONデータの**エンコード・デコードはペア**でよく使われる点に注意する。

##まとめ
JSONの操作はオブジェクトデータと同じように扱える

オブジェクトや配列をJSONにエンコード（変換）するには「JSON.stringify()」を使う

JSONをJavaScriptで使う場合には「JSON.parse()」を使う

エンコードとデコードはセットで使う

##参考サイト
メイン
[JSON入門](http://www.tohoho-web.com/ex/json.html)

[【JavaScript入門】JSONの作成とparse() / stringify()の使い方！](https://www.sejuku.net/blog/47716)

[JavaScriptでJSONを生成する方法を現役エンジニアが解説【初心者向け】](https://techacademy.jp/magazine/22425)

MDN
[JSON](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON)

[JSON.parse()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse)

[JSON.stringify()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify)

別途：keyの値などに使用
https://www.ea.com/ja-jp/games/apex-legends/about/characters