【JavaScript】オブジェクトの生成の書き方が複数あるので３パターンに分けてまとめてみた

PHPと違いJavaScriptではオブジェクトを生成する際の記述パターンがいくつかあり、頭の中で整理が出来てなかったので調べてまとめることにしました。

大まかには下記の３パターン
例１） var obj = new Object;
例２） var obj = {};
例３） var obj = function(){};


今回は下記の出力文章を生成する機能を持つオブジェクトを、３つの記述方法で生成します。

```
出力文章：私の名前は「太郎」です。「30」歳「彼女募集中」です。
　　　　　※「」内の値をオブジェクトのプロパティーで定義
```

予備知識
オブジェクト：関連のあるデータと機能の集合体のこと。
プロパティー：オブジェクト内で宣言する変数のこと。
メソッド：オブジェクト内で宣言する関数のこと。


##書き方１  var obj = new Object; 


```javascript:app.js

//書き方１
var profile = new Object;
profile.name = '太郎'; //プロパティ
profile.age = 30; //プロパティ
profile.status = '彼女募集中'; //プロパティ
profile.sayInfo = function(){　// メソッド
    return '私の名前は' + profile.name + 'です。' + profile.age + '歳' + profile.status + 'です';
}
console.log(profile.sayInfo());
```

JavaScriptで用意されているObjectクラスを使い、Objeutクラスのインスタンスを生成した後に、一つ一つプロパティーやメソッドを追加していく記述方法。

予備知識
new：「new演算子」と呼ばれ、インスタンスを生成するための演算子。
インスタンス：予め準備してあるクラスや関数を用いて、実際に利用するオブジェクト(今回でいうとprofile)を生成すること

一目見て変数がオブジェクトと分かるので初心者にとってはありがたいが、書い方が回りくどいため、実務ではこの記述方法は利用されることは少ない。

## 書き方２　var obj = {};

```javascript:app.js
//例２
var profile = {
        name: '太郎', //プロパティー
        age: 30,　//プロパティー
        status: '彼女募集中',　//プロパティー
        sayInfo: function(){　//メソッド
            return '私の名前は' + this.name + 'です。' + this.age + '歳' + this.status + 'です';
    }
};

console.log(profile.sayInfo());

```
連想配列のようにキーとバリューという書き方で、プロパティーやメソッドを記述する方法。こちらの方が実際によく使われる生成方法。

明記していないが、{}で変数を定義することで、暗黙的にObjectクラスのインスタンスとしてprofileオブジェクトを生成している。

つまり書き方の問題で、仕組みとしては書き方１と書き方２は同じ。


書き方１と書き方２は下記のように併用することも可能。

```javascript:app.js

//書き方１と書き方２の併用
var profile = new Object({
        name: '太郎', //プロパティー
        age: 30,　//プロパティー
        status: '彼女募集中',　//プロパティー
        sayInfo: function(){　//メソッド
            return '私の名前は' + this.name + 'です。' + this.age + '歳' + this.status + 'です';
    }
});
```
Objectクラスを使いインスタンス生成する際に、予め引数でプロパティーやメソッドを指定している。
この書き方はコンストラクタという概念らしい。

※コンストラクタについては後述する。


ちなみに関係ない話だけど、この書き方はvue.jsでvue関数を使いvueインスタンスを生成する時の書き方に似ている。

##例３　var obj = function(){};

```javascript:app.js

var Profile = function(){ //functionオブジェクト
    this.name = '太郎',
    this.age = 30,
    this.status = '彼女募集中',
    this.sayInfo = function(){
        return '私の名前は' + this.name + 'です。' + this.age + '歳' + this.status + 'です';
    }
}

var prof = new Profile;　//Profileのインスタンスを生成
console.log(prof.sayInfo());

```
書き方３は、書き方２のようにObjectクラスのインスタンスとしてオブジェクト生成するのではなく、function(関数)をProfileに格納している。

JavaScriptではfunctionもオブジェクトとして考えられており、functionオブジェクトと呼ばれている。

今回は変数Profileにfunctionオブジェクトを格納しているので、Profileのデータ型はfunctionオブジェクトとなっている。

functionオブジェクトとして定義する場合、変数名の1文字目は大文字にするという命名規則があるそうです。

このfunctionオブジェクトのプロパティーやメソッドを利用するためには、new演算子を使いインスタンスを生成する必要があるらしい。

```
var prof = new Profile;　//functionオブジェクトであるProfileのインスタンスを生成
```

このインスタンスという概念が分かりにくかったので、例２と比較してみた。

```javascript

//書き方２の場合
profile.name //太郎
profile.age //30
profile.status //彼女募集中

//書き方３の場合　newでインスタンスしないと
Profile.name //Profile(関数名)
Profile.age //undefined
Profile.status //undefined

```

上記のように、例３ではインスタンスしていないので、Profile.ageとしてもundefinedとなってしまう。

これだけ書くと例３の方法はnew演算子使ったりとややっこしいため、例２だけでいいじゃないかと思ってしまったが、オブジェクトを使い回して利用したい場合は書き方３が非常に適している。

どういうことか具体的に記述してみた。

例えば、今回、オブジェクトとして生成しているprofile。
現実世界で考えると、profileは当然人の数の分存在する。
Aさん、Bさん、Cさんで違ってくる訳だ。

書き方２だとそれぞれの人に対してプロパティーやメソッドを個別に指定する必要がある。

```javascript:app.js

//Aさん
var profile_a = {
    name : '太郎',
    age : 30,
    status : '彼女募集中',
    sayInfo : function(){
        return '私の名前は' + this.name + 'です。' + this.age + '歳' + this.status + 'です';
    }
};


//Bさん
var profile_b = {
    name : '花子',
    age : 29,
    status : '彼氏募集中',
    sayInfo : function(){
        return '私の名前は' + this.name + 'です。' + this.age + '歳' + this.status + 'です';
    }
};

//Cさん
var profile_c = {
    name : '一郎',
    age : 45,
    status : '既婚者',
    sayInfo : function(){
        return '私の名前は' + this.name + 'です。' + this.age + '歳' + this.status + 'です';
    }
};
```

これでも問題ないが、人が増えてくるとコードが長くなってしまうし、nameやageといったプロパティー名は共通しているので何回も書くのが無駄な気がしてならない。

この場合は例３の記述方法を使うと綺麗に書くことができる。



```javascript:app.js

var Profile = function(name,age,status){
    this.name = name,
    this.age = age,
    this.status = status,
    this.sayInfo = function(){
        return '私の名前は' + this.name + 'です。' + this.age + '歳' + this.status + 'です';
    }
}

var profile_a = new Profile('太郎',30,'彼女募集中');
var profile_b = new Profile('花子',28,'彼氏募集中');
var profile_c = new Profile('一郎',45,'既婚者');

console.log(profile_a.sayInfo()); //私の名前は太郎です。30歳彼女募集中です
console.log(profile_b.sayInfo()); //私の名前は花子です。28歳彼氏募集中です
console.log(profile_c.sayInfo()); //私の名前は一郎です。45歳既婚者です
```

上記の方法では、profile_aやprofile_bは、functionオブジェクトであるProfileのインスタンスとして生成されている。
ここで重要なのが、インスタンスとして生成する際には引数を指定することができるということ。
処理の流れとすると、引数で'name' 'age' 'status'のプロパティー値を指定し、インスタンス生成時にProfileで準備してある'name' 'age' 'status'にそれぞれ格納していることになる。

このように、予め準備してあるオブジェクトを使いインスタンス生成して、引数に値をセットし、オブジェクト内の変数へを値を格納する仕組みのことを「コンストラクタ」と呼ぶ。

このコンストラクタの仕組みを使うことで、共通の属性や機能を持つインスタンスを、一つのオブジェクトを使い大量に生成できる。

##まとめ

以上、JavaScriptでオブジェクト生成する記述方法３パターンについてまとめてみた。

まとめてみた結果、単純にObjectクラスのインスタンスとしてオブジェクト生成する方法が書き方１・書き方２。

一方、インスタンスする元となるオブジェクト自体を自分自身で定義し、自分で準備したオブジェクトのインスタンスとして生成する方法が書き方３。


ちなみに書き方３はさらに詳細な記述方法があり、PHPでいうクラスの継承や、プロパティのアクセス修飾子もJavaScriptではJavaScrptとして実装する方法があるらしい。

次回はその方法についてまとめてみたい。