【ド基礎から始めるJS講座②】Objectが解った気がするので調子に乗ってclassを作ってみる

# はじめに

前回の [【ド基礎から始めるJS講座①】Objectが解ればJSの半分くらいは解った気になれる！](https://qiita.com/layzy_glp/items/8eef954eac74bf974d4a) はそこそこ役に立ったでしょうか？
ちょっと内容が薄かったので。調子に乗ってclassの話までしたので、そこの部分もテキスト化しますね。

# mitsuha爆誕

深海映画の「君の名は。」には瀧くんと入れ替わっちゃう三葉という女の子がいます。
序盤でご飯をクッチャクッチャしてンベッて吐いて**美少女JKの口噛み酒**と言うフェチズムに満ちたアイテムを爆誕させる娘です。

彼女を瀧くんと同じようにObjectであらわすとこんなかんじですかね。

```javascript
const mitsuha = {
    name: {
        familyName: 'miyamizu',
        firstName: 'mitsuha'
    },
    sex: 'woman',
    age: 20, //瀧より3歳上という設定なので
    getFullname: function(){
        return mitsuha.name.familyName + mitsuha.name.firstName;
    }
}
```

せっかくなんで、瀧君と並べてみましょうか。

```javascript
const taki = {
    name: {
        familyName: 'tachibana',
        firstName: 'taki'
    },
    sex: 'man',
    age: 17,
    getFullname: function(){
        return taki.name.familyName + ' ' + taki.name.firstName;
    }
}

const mitsuha = {
    name: {
        familyName: 'miyamizu',
        firstName: 'mitsuha'
    },
    sex: 'woman',
    age: 20,
    getFullname: function(){
        return mitsuha.name.familyName + ' ' + mitsuha.name.firstName;
    }
}
```

こう……なんか不毛な感じがないですか？
おんなじような構造に見えるんだが……そう、その気持ちは正しいです。

# classでくくりだそう

`taki`と`mitsuha`の2つをよく見ると、個々の値が違うだけで、プロパティそのものの構造が一緒なことに気がつくと思います。っていうか、一緒にしたんですけどね。
と言うことはこれ、数学で言うところの「共通因数でくくる」みたいなことができやしまいか？って思いますよね？
思わない人はきっとプログラミング向いてない気がします。
大丈夫、あなたが活躍できるところはきっとどこか別にある！

さて、このくくりだしたものを表現するために`class`というものがあります。
`class`はオブジェクト指向プログラミングの本丸であるところのアレです。
瀧と三葉の共通点……それは**二人とも人間である**というところですよね。
というわけで、`Human`(人間)というクラスを作ってみましょう。

```javascript
class Human {
    // コンストラクターメソッド。インスタンスを生成するときに初期値を設定する。
    constructor(firstName, familyName, sex, age) {
        this.name = {
            firstName: firstName,
            familyName: familyName
        };
        this.sex = sex;
        this.age = age;
    }

    getFullname() {
        return this.name.familyName + ' ' + this.name.firstName;
    }
}
```

こんな感じでしょうか。要はこれ、Objectを作るときの設計図みたいなもんです。
この`class`を使って`taki`を作るときはこんな感じにします。

```javascript
const taki = new Human('taki', 'tachibana', 'man', 17);
```

takiを定義するときに`Human`の前に`new`を付けて、`Human`の後ろのカッコに初期値を入れるだけです。
ぐっと楽になったと思いませんか？
ちなみにこの`class`に`new`を付けて作り出されたObjectは**インスタンス**と呼ばれます。

調子に乗って`mitsuha`も作ってみましょう。

```javascript
const mitsuha = new Human('mitsuha', 'miyamizu', 'woman', 20);
```

こんなふうに気楽にポンポコと同じ作りのObjectを作ることができます。

# thisってなんだ？

`class`の中を見ると`this`と言うのが多用されているのがわかるかと思います。
そして各々のプロパティの定義が`this.プロパティ名 = 値;`みたいな感じになってますよね。

`class`はObjectの設計図ではありますが、Objectの記法を用いているわけではありません。
もともと文法自体よその言語とはかけ離れていたので、ここ数年で似たような書き方ができるようにバージョンアップされました。
よく似た名前の言語であるJavaの書き方に似せて書けるようになったのです。

話を戻しましょう。
`this`はインスタンスそのものを抽象的に表現しています。
インスタンス化するときにインスタンスの名前は好きなものをつけることができるので。

わかりやすいようにくくりだされる前の素の`taki`の`getFullName`メソッドとclassに定義されている`getFullName`メソッドを見比べてみましょう。

```javascript
const taki = {
    getFullname: function(){
        return taki.name.familyName + ' ' + taki.name.firstName;
    }
}

class Human {
    getFullname() {
        return this.name.familyName + ' ' + this.name.firstName;
    }
}
```

ちょうど、`taki`のところが`this`になってるのがわかりますよね。

# classと言う書き方はいにしえのJavaScriptでは使えない

以前……というか、ES5より前の時代ではこの書き方では動きません。。。
っていうか変数宣言の`const`とか`let`とかもそうなんですけどね。
とは言え、classっぽいことは昔からできていました。
そう、**コンストラクタ関数**という、特別な関数を用います。
さっきのclassをコンストラクタ関数で表現してみましょう。

```javascript
function OldHuman(firstName, familyName, sex, age) {
    this.name = {
        firstName: firstName,
        familyName: familyName
    };
    this.sex = sex;
    this.age = age;

    this.getFullname = function () {
        return this.name.familyName + ' ' + this.name.firstName;
    };
}

var oldTaki = new OldHuman();
```

# おわりに

「classってなんだか難しいそう……」みたいなことはJS初心者だけでなくて、プログラミング初心者共通の悩みだったりするかと思います。
ですが、結局は「おんなじようなObjectいくつもつくるのめんどくさい」「変数名かぶり気にしてるのツラい」とか、そういうのを嫌がる横着者プログラマのための機能ですので、皆さん存分に横着しましょう。

怠惰はプログラマー三大美徳の一つですよ👍

# おまけ

@miriwo　さんがPHP版の似たような記事を書いてくれました！
[PHP 今更ながらオブジェクト指向を自分自身に向けて解説してみた ~基本編~](https://qiita.com/miriwo/items/2b379f4ab0970903d28a)