乃木坂46で、クラス・インスタンス・コンストラクタを理解する

自分の理解を整理するためにQiitaに書きます。
jQueryコピペエンジニアからフロントエンドエンジニアになるための第一歩として、
クラスとインスタンスの理解が不可欠かと...
色々調べてもよくわからなかったので、自分の大好きな乃木坂46に例えて説明してみます。
以下まとめます。
キーワードは

- **オブジェクト**
- **クラス**
- **インスタンス**
- **コンストラクタ**

かな？

#オブジェクトとは？
**モノの特性や動作の情報をまとめた箱**みたいなもの。
特性を**プロパティ**、動作を**メソッド**と呼ぶ。

例えば...
西野七瀬オブジェクトがあるとします。
そうするとプロパティとメソッドは以下のように整理できるでしょう。

- プロパティ
    - 名前:西野七瀬
    - 職業:アイドル
    - 所属:乃木坂46
    - 事務所:sonymusic
    - 血液型:O型
    - 身長:159cm
    - 容姿:世界一のかわいさ

- メソッド
    - 歌う
    - 踊る
    - ウインクする
    - 泣く

Javascriptの文脈では以下のように定義できる。

```Javascript:なぁちゃんオブジェクトを作る！
var nanase = {
   'name' : 'Nishino',
   'job' : 'idol',
   'department' : 'nogizaka46',
....
//ここまでがプロパティ
   'singSong' : function() {
       console.log("ummmmmmm");
   };
....
//ここまでがメソッド
}
```

#クラスとは？
まず最初に、**javascriptではクラスという概念は存在しない**...(まじかよ)
ただ、理解を進めるために説明を続けます。
**クラス**とは、**とある共通の特性・動作をまとめて定義してある箱**みたいなもの。
例えば、なあちゃん(西野七瀬)もまっつん(松村沙友理)まいやん(白石麻衣)も、
「職業がアイドルであること」、「乃木坂46に所属していること」、「事務所がsony musicであること」は共通点です。
つまり、なあちゃんオブジェクトとまっつんオブジェクトとまいやんオブジェクトの共通点をまとめた箱がクラスな訳です。
以上を乃木坂46クラスとすると、以下のように整理できます。
###乃木坂46クラス
- プロパティ
    - 職業:アイドル
    - 所属:乃木坂46
    - 事務所:sonymusic

- メソッド
    - 歌う
    - 踊る

#インスタンスとは？
**クラスに基づいて生成されるオブジェクト**のこと。
例えると、クラスが乃木坂46、最近新加入した3期生メンバーがインスタンスといえます。
乃木坂46クラスから、大園桃子オブジェクトを生成するという表現でしょうかね。

インスタンスの概念の意味はなんでしょうか？
以下2点あります。

## 1. **効率的にオブジェクトを生成するため**
オブジェクトを生成するときに、いちいち「○○プロパティがあって、○○メソッドがあって..」と定義するのは非常に面倒臭い。だから、あらかじめ共通点をクラスに定義しておけば楽なわけです。
乃木坂のメンバー募集するたびに「乃木坂のコンセプトはこうで、こういうグループで..」って定義するのは面倒臭いですよね。
だから、あらかじめメンバーの共通点を定義しておくわけです。そうすると新しいメンバーをオーディションしやすいわけですね。

## 2. **オリジナルのオブジェクトの情報を上書きさせないため**
オリジナル(大元)のオブジェクトを、ここでは乃木坂46の1期生とします。
正直、新しく入ってきた3期生に1期生が作ってきた乃木坂の雰囲気やコンセプトをぶち壊されたらたまったもんじゃないですよね。
だから、「大元の乃木坂46のコンセプトイメージから生み出されたメンバーなら大丈夫」となるわけです。
言い換えると、「乃木坂46クラスから生み出された3期生インスタンスなら安心」ということです。
新たに3期生オブジェクトを生成しようとしたら、どんな特性が入るかわからんので危険です。
プログラミング的に言い換えると、「オブジェクトを扱うための自分専用の領域を確保した」ことになります。
自分の情報がどうであれ、大元のオブジェクトは上書きできないから、という意味合いなのでしょう。　

#コンストラクタとは？
**インスタンス生成のための関数**のこと。
Javascriptではクラスという考えがないので、このコンストラクタからインスタンスを生成します。
ここで、コンストラクタを理解するためには「初期化」という考え方を学ばなければなりません。
##初期化とは？
インスタンスを生成するときに同時に行わなければならない行為のこと。
先ほど、インスタンスを生成すること(インスタンス化)は「オブジェクトを扱うための自分専用の領域を確保すること」と説明しました。
実は、この確保した領域には最初ゴミが入っています。
なので、このインスタンス化したオブジェクトに期待通りの動きをさせるように、まっさらな状態にすることを初期化というのです。
例えるなら、3期生オブジェクトを作るときに、その3期生の過去データ(彼氏とのプリクラなど..笑)を消去しておくわけですね。これがオブジェクトの初期化です。

話をコンストラクタへ戻します。
javascriptでは、オブジェクト(インスタンス)を生成する際には「初期化→インスタンス化」という流れを踏まなければなりません。
その初期化をする関数をコンストラクタというのです。
以下コードです。

```Javascript:コンストラクタ
var Member = function(name, age){
    this.name = name;
    this.age = age;
};
```
上記でどうして初期化されるのかよくわかりませんでしたが、
どうやら内部で新しい配列を生成して、その中に入れる、という動作が行われているようです。

そして、インスタンス(例えると3期生)を生成してみます。

```Javascript:インスタンス
var oozono = new Person("momoko", 16);
```

new演算子はググってくれ。とにかくインスタンスを生みだすためのものと捉えてください。
こうやってインスタンスが生成できました。

#まとめ
javascriptはクラスがない？　ってことは効率的にオブジェクトを生成するっていう話はどこいった？と個人的な疑問です。毎回初期化したりなんも効率的じゃないやんなんやこれ？と思ったら、どうやら「プロトタイプ」という概念があるようです。これは後日まとめてみたいと思います。
以上、初投稿でした。
捉え方が違う等ございましたらご教示くださいませ。

#参考にしたページ
- [JavaScriptのクラス？コンストラクタ？？](http://qiita.com/takeharu/items/010752b1427773558f7c)
- [オブジェクトを初期化する、とは](https://teratail.com/questions/32485)
- [JavaScriptのコンストラクタによるインスタンス生成](http://uxmilk.jp/30348)