JavaScript アドバンス

JavaScript クラスの継承

1. クラスの継承

JavaScript でクラスの継承を作成するには、extends キーワード(Keyword)を使用します。
継承によって作成されたクラスは、別のクラスからすべてのメソッドを引き継ぐことができます。

「Car」クラスからメソッドを継承する「Model」という名前のクラスを作成します:

class Car {
  constructor(brand) {
    this.carname = brand;
  }
  present() {
    return '私は ' + this.carname + ' を持っています';
  }
}

// Car クラスを継承
class Model extends Car {
  constructor(brand, mod) {
    // 親クラスのコンストラクタを呼び出す
    super(brand);
    this.model = mod;
  }
  show() {
    return this.present() + '、モデルは ' + this.model + ' です';
  }
}

let myCar = new Model("Ford", "Mustang");
document.getElementById("demo").innerHTML = myCar.show();

super() メソッドは親クラスを参照します。
コンストラクタメソッド内で super() を呼び出すことで、親クラスのコンストラクタメソッドを実行し、親クラスのプロパティやメソッドにアクセスできるようになります。

継承は、コードの再利用性(Code Reusability)に非常に役立ちます。新しいクラスを作成する際に、既存のクラスのプロパティやメソッドをそのまま再利用できるためです。

2. Getter と Setter

クラスでは、Getter(ゲッター)と Setter(セッター)を使用することもできます。
プロパティに対して Getter/Setter を使用することは、値を返す前や設定する前に特定の処理(バリデーションや加工など)を行いたい場合に非常にスマートな手法です。

クラスにこれらを追加するには、get および set キーワードを使用します。

"carname" プロパティに対して Getter と Setter を作成します:

class Car {
  constructor(brand) {
    this.carname = brand;
  }
  get cnam() {
    return this.carname;
  }
  set cnam(x) {
    this.carname = x;
  }
}

const myCar = new Car("Ford");

// プロパティとしてアクセス(カッコは不要)
document.getElementById("demo").innerHTML = myCar.cnam;
Getter はメソッドとして定義されますが、値を取得する際に括弧 () は使用しません

また、Getter/Setter メソッドの名前を、実際のプロパティ名(この場合は carname)と同じにすることはできません。
多くのエンジニアは、実際のプロパティ名の前にアンダースコア _ を付けて、Getter/Setter と区別する慣習を持っています。

アンダースコアを使用して、Getter/Setter と実際のプロパティを分離する例:

class Car {
  constructor(brand) {
    this._carname = brand;
  }
  get carname() {
    return this._carname;
  }
  set carname(x) {
    this._carname = x;
  }
}

const myCar = new Car("Ford");

document.getElementById("demo").innerHTML = myCar.carname;

Setter を使用する場合も、プロパティに値を代入する時と同じ構文を使用します(括弧は不要です):

Setter を使用して車名を "Volvo" に変更します:

class Car {
  constructor(brand) {
    this._carname = brand;
  }
  get carname() {
    return this._carname;
  }
  set carname(x) {
    this._carname = x;
  }
}

const myCar = new Car("Ford");
// Setter の呼び出し
myCar.carname = "Volvo";
document.getElementById("demo").innerHTML = myCar.carname;

3. ホイスティング (Hoisting)

関数や他の JavaScript 宣言とは異なり、クラス宣言はホイスティング(巻き上げ)されません。
つまり、クラスを使用する前に、必ずそのクラスを宣言しておく必要があります。

宣言の前にクラスを使用しようとするとエラーが発生します:

// まだクラスは使用できません。
// myCar = new Car("Ford") はエラーを発生させます。

class Car {
  constructor(brand) {
    this.carname = brand;
  }
}

// クラスを宣言した後であれば使用可能です:
const myCar = new Car("Ford");
関数などの他の宣言では、宣言の前に使用してもエラーになりません。これは JavaScript のデフォルトの挙動であるホイスティング(宣言をスコープの最上位に移動させる処理)が機能するためですが、クラスにおいてはこの挙動は適用されません。