クラスでオブジェクトを作る方法

JavaScriptは、型をベースに独自のオブジェクトを作ることができます。

本ページでは、クラスからオブジェクトを作る方法を説明します。

クラスとは

クラスとは、オブジェクトの型でプロパティやメソッドなどを定義します。プロパティに値を入れてインスタンス化することで、実体のオブジェクトが作成できます。

クラスとオブジェクト

JavaScriptは、これまでコンストラクタ関数をクラスのように使って型にしていましたが、新しくclassを使ってクラスが作れるようになりました。

ただし、classはInternet Explorerでサポートされていません。

クラス宣言

以下は、クラス宣言によるオブジェクトの作り方です。

【クラス宣言の例】
//クラス宣言
class Peaple {
  constructor(address, birthday) {
    this.address = address;
    this.birthday = birthday;
  }
  display() {
    alert("住所は" + this.address + "で生年月日は" + this.birthday + "年");
  }
}

//インスタンス化
const yamada = new Peaple("Tokyo",2001);

上記は、addressとbirthdayプロパティ、displayメソッドがあるオブジェクトの型を作っています。最後のconst yamadaでインスタンス化しています。つまり、yamada.addressは"Tokyo"、yamada.birthdayは2001になります。

const suzuki = new Peaple("Kyoto",1999)などとすると、同じプロパティとメソッドを持つ別のインスタンスが作成できます。

この時、yamadaやsuzukiのプロトタイプは、Peaple.prototypeです。このため、Peaple.prototype.country = "Japan"とすると、yamada.countryもsuzuki.countryも"Japan"になります。

クラス式

以下は、クラス式による作り方です。

【クラス式の例】
//クラス式
const Peaple = class {
  constructor(address, birthday) {
    this.address = address;
    this.birthday = birthday;
  }
  display() {
    alert("住所は" + this.address + "で生年月日は" + this.birthday + "年");
  }
}

//インスタンス化
const yamada = new Peaple("Tokyo",2001);

結果は、クラス宣言で作った時と同じです。

静的プロパティとメソッド

インスタンスからアクセスできないプロパティとメソッドを作ることもできます。

【静的プロパティとメソッドの作成例】
class Peaple {
  constructor(address, birthday) {
    this.address = address;
    this.birthday = birthday;
  }
  static country = "Japan";
  static display(a, b) {
    alert("住所は" + this.country + "の" + a.address + "で生年月日は" + a.birthday + "年");
    alert("住所は" + this.country + "の" + b.address + "で生年月日は" + b.birthday + "年");
  }
}
const yamada = new Peaple("Tokyo",2001);
const suzuki = new Peaple("Kyoto",1999);
Peaple.display(yamada, suzuki);

上記は、最後の行を実行した時に「住所はJapanのTokyoで生年月日は2001」と、「住所はJapanのKyotoで生年月日は1999」が表示されます。

staticで定義したプロパティやメソッドは、yamada.couuntryやsuzuki.display()などでアクセスはできません。つまり、間違った使い方をされるのを防げます。

サブクラス

共通で使うクラスを作り、そのプロパティなどを共有するサブクラスを作ることもできます。

【サブクラスの作成例】
//スーパークラス
class Peaple {
  constructor() {
    this.country = "Japan";
  }
}

//サブクラス
class Address extends Peaple {
  constructor(address) {
    super();
    this.address = address;
  }
}

//サブクラス
class Birthday extends Peaple {
  constructor(birthday) {
    super();
    this.birthday = birthday;
  }
}

const yamada1 = new Address("Tokyo");
const yamada2 = new Birthday(2001);

extendsに続けて、親となるクラス(スーパークラス)を指定します。スーパークラスのプロパティは継承されるため、yamada1.countryもyamada2.countryも"Japan"になります。つまり、スーパークラスのプロパティ値を各オブジェクトで共通して利用できます。

super()は、スーパークラスの関数(上記ではコンストラクタ関数)を呼び出します。thisを使う前に記述しないと、エラーになります。

また、上記ではyamada1のプロトタイプはAddress.prototypeで、Address.prototypeのプロトタイプはPeaple.prototypeになります。このため、Peaple.prototype.国 = "日本";を実行すると、継承によってyamada1.国も"日本"になります。

super

superでは、インスタンス化する時、サブクラスからスーパークラスに値を渡すこともできます。

【superで親に値を渡す例】
//スーパークラス
class Peaple {
  constructor(country) {
    this.country = country;
  }
}

//サブクラス
class Address extends Peaple {
  constructor(country, address) {
    super(country);
    this.address = address;
  }
}

const yamada = new Address("Japan", "Tokyo");

yamada.countryは"Japan"、yamada.addressは"Tokyo"になります。

もし、const suzuki = new Address("日本", "Kyoto");を実行すると、yamada.countryは"Japan"で、suzuki.countryは"日本"になります。つまり、スーパークラスで共通の型を使っていますが、値は別にすることができます。

また、メソッドを呼び出すこともできます。

【superでメソッドを呼び出す例】
//スーパークラス
class Peaple {
  dis(a, b) {
    let y = "住所は" + a + "で生年月日は" + b + "年";
  }
}

//サブクラス
class Address extends Peaple {
  constructor(address, birthday) {
    super();
    this.address = address;
    this.birthday = birthday;
  }
  display() {
    super.dis(this.address, this.birthday);
  }
}

const yamada = new Address("Tokyo", "2001");

super.に続けて、スーパークラスの関数を指定します。

上記で、yamada.display();を実行すると、yに"住所はTokyoで生年月日は2001年"が代入されます。

複数サブクラスを作ったとしても、共通でスーパークラスのメソッドが使えるという訳です。