【javascript】クラス

こちらの記事は以下の書籍を参考に執筆しました

- [入門JavaScriptプログラミング](https://www.amazon.co.jp/%E5%85%A5%E9%96%80JavaScript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-JD-Isaacks/dp/479815864X/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1F76CKY9CIJ66&dchild=1&keywords=%E5%85%A5%E9%96%80javascript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0&qid=1595991879&s=books&sprefix=%E5%85%A5%E9%96%80javascript%2Cstripbooks%2C-1&sr=1-3)


#クラス定義でインスタンスプロパティを設定する
各メソッドは**プロトタイプ**に追加されるが
プロパティは**各インスタンス**に割り当てられる。

```javascript
class DateStore {
  url = '/data/resources';
  records = [];
  fetch() {
    ajax(this.url, records => this.records = records);
  }
}
console.log(DateStore.url)//undefined
const store = new DateStore()
console.log(store.url)///data/resources
console.log(store.records.length)//0
```
>出典：[入門JavaScriptプログラミング](https://www.amazon.co.jp/%E5%85%A5%E9%96%80JavaScript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-JD-Isaacks/dp/479815864X/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1F76CKY9CIJ66&dchild=1&keywords=%E5%85%A5%E9%96%80javascript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0&qid=1595991879&s=books&sprefix=%E5%85%A5%E9%96%80javascript%2Cstripbooks%2C-1&sr=1-3)



このように、クラスプロパティはインスタンスで使用可能になる。
これはコンストラクタメソッドの中で設定されたように処理される。

```javascript
class DateStore {
  constructor() {
    url = '/data/resources';
    records = [];
  }
}
```
>出典：[入門JavaScriptプログラミング](https://www.amazon.co.jp/%E5%85%A5%E9%96%80JavaScript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-JD-Isaacks/dp/479815864X/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1F76CKY9CIJ66&dchild=1&keywords=%E5%85%A5%E9%96%80javascript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0&qid=1595991879&s=books&sprefix=%E5%85%A5%E9%96%80javascript%2Cstripbooks%2C-1&sr=1-3)



##プロパティをプロタイプに直接設定するのは**バグ**のもと
クラスメソッドはクラスのプロトタイプに追加される。
メソッドはプロトタイプ継承され、インスタンスに継承される。

対して、クラスプロパティはプロタイプに追加されず、インスタンスで直接割り当てられる。

```javascript
class DataStore {}

DataStore.prototype.records = []

const storeA = new DataStore()
console.log(storeA.records.length)//0

const storeB = new DataStore()
console.log(storeB.records.length)//0

storeB.records.push('Example Record')

console.log(storeA.records.length)//1
console.log(storeA.records[0])//Example Record
```
>出典：[入門JavaScriptプログラミング](https://www.amazon.co.jp/%E5%85%A5%E9%96%80JavaScript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-JD-Isaacks/dp/479815864X/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1F76CKY9CIJ66&dchild=1&keywords=%E5%85%A5%E9%96%80javascript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0&qid=1595991879&s=books&sprefix=%E5%85%A5%E9%96%80javascript%2Cstripbooks%2C-1&sr=1-3)



recordsプロパティなhDataStoreのインスタンスではなくDataStoreのプロトタイプのプロパティに直接設定されている。
つまり、すべてのインスタンスが同じrecords配列を使用するということ。
すべてのオブジェクトが同じrecords配列を共有していることが問題。

#静的プロパティ
クラスのオブジェクト(コンストラクタ)で設置される特殊なプロパティ。
インスタンスでもプロトタイプでも設定されない。
静的プロパティはインスタンス間で変化しない。

```javascript
class DataStore {
  static domain = 'htt://example.com';//静的プロパティの割当
  static url(path) {                  //静的プロパティの設定
    return `${this.domain}${path}`
  }

  constructor(resource) {
    this.url = DataStore.url(resource) //静的メソッドの呼び出し
  }
}

const userStore = new DataStore('/users')
console.log(userStore.url)//htt://example.com/users
```
>出典：[入門JavaScriptプログラミング](https://www.amazon.co.jp/%E5%85%A5%E9%96%80JavaScript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-JD-Isaacks/dp/479815864X/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1F76CKY9CIJ66&dchild=1&keywords=%E5%85%A5%E9%96%80javascript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0&qid=1595991879&s=books&sprefix=%E5%85%A5%E9%96%80javascript%2Cstripbooks%2C-1&sr=1-3)