オブジェクト指向初心者の私がJavaScriptにも再入門 「配列・JSON編」 〜JavaScriptパターン 学習4日目【逃げメモ】〜


#タイトルを変更しました

逃げる前にメモしよう、略して「逃げメモ」シリーズも4回目となりました。

前回の記事をリツイートして下さった方が、 **「タイトルで損をしている」**と感想を述べられていしらっしゃいました。

確かに「2日目とか3日目とかだけ言われてもなー」と思いましたので、ちょっとタイトルを変えてみました。あんまり変わってないですが、何が書かれているかはパッと見分かるのでこれで行く事にします。

宜しくお願いします。

さて、本題に入りますねー。

# リテラルとコンストラクタ

## 配列

配列も **オブジェクト**であり、オブジェクトと同じように、`new`にて配列コンストラクタを使用してオブジェクトを生成する方法と、リテラルにて生成する方法とがあるようです。

リテラルで書く場合、宣言は`var a = [];`のように角括弧で覆うように書きます。オブジェクトリテラルは`var a = {};`でしたね。

配列に`typeof`演算子を使っても`[object Object]`と返って来てしまい、オブジェクトと見分けが付かないので`Object.prototype.toString.call(hoge)`で判定すると良いみたいです。

```js:配列の宣言
//newで宣言するパターン
var theLights = new Array("REMIND", "UNFOLD", "式日");
console.log(Object.prototype.toString.call(theLights)); //[object Array]

//リテラル記法パターン
var theStars = ["FREE STAR", "銀河の街", "star rain"];
console.log(Object.prototype.toString.call(theStars)); //[object Array]

//参考:オブジェクトの場合
function Finals() {
   this.song1 = "TO THE WORLDS END";
   this.song2 = "世界が終わる夜";
   this.song3 = "最期の景色";
}

var theFinal = new Finals();
console.log(Object.prototype.toString.call(theFinal)); //[object Object]

```

配列の宣言をする際、渡す値が数値の場合は注意が必要で、見た目こそそこまで違わないのですが、意味合いが違うので読み間違えないようにしておくのが良いと思われます。

```js:配列の宣言の渡す値が数値の場合
var arrObjOne = [3]; //数値:3というものが1つ入った配列を宣言
console.log(arrObjOne.length); // 1
console.log(arrObjOne[0]) // 3 <-- 配列の0番目の値は3

var arrObjTwo = new Array(3); //中身が空の配列を3つを持つ配列を宣言
console.log(arrObjTwo.length); // 3
console.log(arrObjTwo[0)); // undefined <-- 中身は空である
```

# JSON

JavaScript Object Notationの略で、データ転送フォーマットです。扱いが楽なので色々な言語やサービスに使われています。

PHPかなんかでリクエストを送って返ってくる値をJSON形式にしておけば、JS側で扱いが楽なので、そういう仕組みしておくと面白いかもしれませんね！

## 文字列でJSONを表現

まず、JSON型の文字列をオブジェクトへ変換（パース）する方法を見てみましょう。

```js:パース
//文字列でJSON形式を表現
var jsonStr = '{"title":"宇宙系名作","songs":["migration10 64","銀河の街","千年歩行"],"artist":"ACIDMAN","memberCount":3}';

//JSONデータをオブジェクトへパース
var jsonObj = JSON.parse(jsonStr);

//出力
console.log(jsonObj.memberCount + "人組アーティスト" + jsonObj.artist + "の" + jsonObj.title);

//配列の出力
for (var i = 0, max = jsonObj.songs.length; i < max; i++) {
   console.log(jsonObj.songs[i]);
}

/*出力>>
3人組アーティストACIDMANの宇宙系名作
migration10 64
銀河の街
千年歩行
*/
```


パースを行えば、オブジェクトとしてJSON型文字列があつかえるようになります。

Webサービスから発行されるJSON型文字列値をJavaScriptで受けてオブジェクトにパースして使うのは、こんなにカンタンなんですね。便利。

## 記法
オブジェクトと配列を使って表現できます。

キーはダブルコーテーション("")にて囲む必要があり、キーと値の間はコロン(:)でわけられ、配列なら角括弧([])、オブジェクトなら波括弧({})を使います。

通常の数値やブーリアン値ならダブルコーテーションなし、文字列ならダブルコーテションを付けます。nullも入れられます。

関数などは基本的に扱えません。


## オブジェクトや配列をJSON形式にシリアライズ

オブジェクトや配列を`JSON.stringify(obj)`を実行することで、JSON形式に変換（シリアライズ）する事ができます。

```js:シリアライズ
/*** リテラル記法でオブジェクト生成 ***/

var theme = {
   title: "宇宙系名作",
   songs: [
      "migration10 64",
      "銀河の街",
      "千年歩行"
   ],
   artist: "ACIDMAN",
   memberCount: 3,
   position: {
      guitar: "大木",
      bass: "サトマ",
      drums: "テンピュール"
   }
}

//オブジェクトをJSON形式へシリアライズ
var jsonStr = JSON.stringify(theme);

//出力
console.log("jsonStr:" + jsonStr); //jsonStr:{"title":"宇宙系名作","songs":["migration10 64","銀河の街","千年歩行"],"artist":"ACIDMAN","memberCount":3,"position":{"guitar":"大木","bass":"サトマ","drums":"テンピュール"}}


/*** カスタムコンストラクタでオブジェクト生成 ***/

function Theme2() {
   this.title = "宇宙系名作";
   this.songs = [
      "migration10 64",
      "銀河の街",
      "千年歩行"
   ];
   this.artist = "ACIDMAN";
   this.memberCount = 3;
   this.position = {
      guitar: "大木",
      bass: "サトマ",
      drums: "テンピュール"
   }
}

//オブジェクト生成
var theme2 = new Theme2();

//オブジェクトをJSON形式へシリアライズ
var jsonStr2 = JSON.stringify(theme2);

//出力
console.log("jsonStr2:" + jsonStr2); //jsonStr2:{"title":"宇宙系名作","songs":["migration10 64","銀河の街","千年歩行"],"artist":"ACIDMAN","memberCount":3,"position":{"guitar":"大木","bass":"サトマ","drums":"テンピュール"}}
```

## プリミティブなラッパーオブジェクト

数値は`Number()`オブジェクト、文字列は`String()`オブジェクト、ブーリアンは`Boolean()`オブジェクトと言われるラッパーオブジェクトを持っています。

通常、オブジェクトは`new`を行う事で生成されますが、プリミティブ型は、`var artist = "ACIDMAN';`のように、簡潔な記法で生成することができます。

ラッパーオブジェクトを使用する場合は、簡潔な記法で生成した変数に直接ラッパーオブジェクトの持つ関数を呼び出す事で、裏側でプリミティブ型がオブジェクト型に変換され、通常持ち合わせていない関数を呼び出す事ができます。

```js:ラッパーオブジェクトの振る舞い
var artist = "ACIDMAN";
console.log(artist.substring(0,2)); //AC
```

ラッパーオブジェクトを`new`なしで呼び出すと、渡された引数をプリミティブに変換します。

```js:ラッパーオブジェクトをnewなしで呼び出す
//文字列の生成
var migration = "1064";

//数値型に変換
var parse = Number(migration);

console.log(parse + ":" + typeof parse); //1064:number
```

文字列から数値に変換したい際、`Number()`のラッパーオブジェクトを呼び出す事で行えますが、文字列に数字以外が含まれていた場合、実行時エラーとはならず、NaN(Not a Number)が返って来ますので、ソレを検知して正しい処理を行うと良いでしょう。

```js:ラッパーオブジェクトを用いた数値への変換
//文字列の生成(間にスペースを入れてみる)
var migration = "10 64";

//実行時エラーなどは出さずに数値型に変換されてしまう
var parse = Number(migration);

console.log(parse + ":" + typeof parse); //NaN:number <-- 変換はされるがNaNエラー

//なので変換を行う際には isNaNでチェックをしてそれなりの対処を行う
if (isNaN(parse)) {
   console.log("正しく変換されませんでした");
}
```

# リンク

次回はこちら
[オブジェクト指向初心者の私がJavaScriptにも再入門 「関数・コールバック編」 〜JavaScriptパターン 学習5日目【逃げメモ】〜](http://qiita.com/syakegon/items/d7ee99e3cc7a7259fb9e)

前回はこちら

[オブジェクト指向初心者の私がJavaScriptにも再入門 「オブジェクトとコンストラクタ編」 〜JavaScriptパターン 学習3日目【逃げメモ】〜](http://qiita.com/syakegon/items/a0d87f0a5409383289eb)