[JS] Class

classの初期化
---
#####constructor関数
constructor(　)はclassが初期化されるタイミングで必ず呼ばれる関数です

#####new演算子
初期化を行います
初期化する作業を「インスタンス化」と言います

---
このコードだと

```
class TextAnimation {
    constructor(el) {
        alert(el);
    }
}

new TextAnimation('hello world');
```

[![Image from Gyazo](https://i.gyazo.com/582d33be7bda5451d59375bb0310db83.png)](https://gyazo.com/582d33be7bda5451d59375bb0310db83)

初期化されたタイミングでhello worldをalertします

---
thisを使ってnew演算子を使って初期化を行なった変数に格納することができます
この場合のthisはtaを表します

```
class TextAnimation {
    constructor(el) {
        this.el = el;
    }
}

const ta = new TextAnimation('hello world');
alert(ta.el);
```

[![Image from Gyazo](https://i.gyazo.com/582d33be7bda5451d59375bb0310db83.png)](https://gyazo.com/582d33be7bda5451d59375bb0310db83)

thisというプロパティに値を格納することによって
初期化した後の変数に値を格納したり、メソッドを格納したりすることができます

---
値を格納して（this.el = el;）、その値をメソッド内で使用することができる（console.log(this.el);）のがclassという演算子の利点です

```
class TextAnimation {
    constructor(el) {
        this.el = el;
    }
    log() {
        console.log(this.el);
    }
}

const ta = new TextAnimation('hello world');
ta.log();
```

[![Image from Gyazo](https://i.gyazo.com/29ee294773597e0efbd202e52294442a.png)](https://gyazo.com/29ee294773597e0efbd202e52294442a)

---
####classを使ってリファクタリング

```
document.addEventListener('DOMContentLoaded', function () {
    const el = document.querySelector('.animate-title');
    const el2 = document.querySelector('.animate-title-2');
    const str = el.innerHTML.trim().split("");
    const str2 = el2.innerHTML.trim().split("");
    
    let concatStr = '';

    for(let c of str) {
        c = c.replace(/\s+/, '&nbsp;');
        concatStr += `<span class="char">${c}</span>`;
    }

    el.innerHTML = str.reduce((acc, curr) => {
        curr = curr.replace(/\s+/, '&nbsp;');
        return `${acc}<span class="char">${curr}</span>`;
    }, "");
    el2.innerHTML = str2.reduce((acc, curr) => {
        curr = curr.replace(/\s+/, '&nbsp;');
        return `${acc}<span class="char">${curr}</span>`;
    }, "");
});
```

[![Image from Gyazo](https://i.gyazo.com/852206159556726aaeacccc2283d78a0.png)](https://gyazo.com/852206159556726aaeacccc2283d78a0)

これを


```
document.addEventListener('DOMContentLoaded', function () {
    const ta = new TextAnimation('.animate-title');
    const ta2 = new TextAnimation('.animate-title-2');
});

class TextAnimation {
    constructor(el) {
        this.el = document.querySelector(el);
        this.chars = this.el.innerHTML.trim().split("");
        this.el.innerHTML = this._splitText();
    }
    _splitText() {
        return this.chars.reduce((acc, curr) => {
            curr = curr.replace(/\s+/, '&nbsp;');
            return `${acc}<span class="char">${curr}</span>`;
        }, "");
    }
}
```

こう書ける

_splitTextのように、先頭にアンダーバーがついているメソッドをPrivate Methodと呼び、
constructorのように何もついていないメソッドをPublic Methodと呼ぶことがある

_splitTextは、classの中以外で使わないでくださいという意味になります
実際はclass外でも使えますが、開発者同士のコミュニケーションの一環です

classとオブジェクト
---
classとobjectの記述

```
const obj = {
  first_name: 'Shun',
  last_name: 'Sato',
  printFullName: function() {
    console.log('hello');
  }
}

class MyObj {
  constructor() {
    this.first_name = 'Shun';
    this.last_name = 'Sato';
  }

  printFullName() {
    console.log('hello');
  }
}

const obj2 = new MyObj();

obj.printFullName();
obj2.printFullName();
```

[![Image from Gyazo](https://i.gyazo.com/edc696e0c749b5d587d0cdcf80a48b98.png)](https://gyazo.com/edc696e0c749b5d587d0cdcf80a48b98)

---
obj2にはprintFullNameメソッドが確認されないが

＿＿proto＿＿　というプロパティに格納されています
＿＿proto＿＿はブラウザが独自に設定しているプロパティです

[![Image from Gyazo](https://i.gyazo.com/d04a6b5546038e2e074c31019e7810d7.png)](https://gyazo.com/d04a6b5546038e2e074c31019e7810d7)

```
obj.printFullName();
obj2.__proto__.printFullName();
```

丁寧にこう書いても結果は同じになりますが、省略できる設定にデフォルトでなっているので書かなくてもOKです。