JavaScriptのクラス(class)

(クラス)
https://developer.mozilla.org/ja/docs/Learn/JavaScript/Objects/Classes_in_JavaScript
https://techplay.jp/column/482

クラス(class)とは、端的にいえばモノの設計書。クラスはモノ(オブジェクト)の設計書であるため、多くのプログラミング言語においてモノ(オブジェクト)を作成する際に必要なものとして定義されることが多い。
JavaScriptでのクラス変数はコンストラクタの中でのみ記載できることや、クラス直下にはfunction(メソッド、関数)のみしか配置できないこと等、独自ルールが存在する。

クラス宣言

関数宣言時に発生するホイスティング(巻き上げ)は、クラス宣言時には発生しない。そのため、クラスを使用したい場合は必ずクラスを使用する前に、クラス宣言を行うことが必要となる。

class Fooclass {
  // ...クラスの内容をここで定義する
}

クラス式

クラス式の場合、その名の通り、式としてクラスを定義することができる。変数に代入するclass式は無名クラスでも名前つきクラスでも可能である。

const fooclass = class {
  // ...クラスの内容をここで定義する
}

コンストラクタ(constructor)とメソッド定義

クラス宣言やクラス式でクラスを定義する際、そのクラスの中身がどのようなものなのかについて、JavaScriptでは主にコンストラクタ(constructor)とメソッドで定義していく。

const fooclass = class {
  constructor(x, y) { /* コンストラクタ */
    this.x = x
    this.y = y
  }
}

constructor()という名前のメソッドがコンストラクタと呼ばれるものである。コンストラクタは定義したクラスからオブジェクトを生成し、初期化する際に実行される特殊な初期化用メソッドである。
constructor()内でthis.xにconstructor()の第一引数xを代入しているが、これは自身のプロパティxに指定された引数の値を設定するという意味となる。
これにより、オブジェクトが自らのプロパティとその値を設定できるようになる。
また、コンストラクタとは別に通常のメソッドもクラスの内容として定義することが可能である。

const fooclass = class {
  constructor(x, y) { /* コンストラクタ */
    this.x = x
    this.y = y
  }
  calc() {  /* メソッド */
    return this.x + this.y  /* x と y を足した値を返却する */
  }
}

上記コードのcalc()がクラス内でのメソッド定義になる。
ここでは、fooclassクラスのプロパティ x と y を足した値を返すメソッドとして定義している。
このようにクラス内でコンストラクタとメソッドを定義することで、クラスからオブジェクトを作成した際に、定義したコンストラクタのプロパティと、メソッドを使用することができるようになる。

オブジェクトの作成(new)

var foo1 = new fooclass(10, 20)

クラスから、クラスのインスタンスであるオブジェクトを作成するためにはnew演算子を用いる必要がある。
上記の例ではfooclassのインスタンス(オブジェクト)が作成され、変数foo1に代入される。
new演算子 + クラス + 括弧でオブジェクトが作成される。この際に登場する括弧は、クラス定義の際に登場したコンストラクタ(constructor)に渡される引数を示す。

プロパティの取得と設定

var hooclass = class {
  constructor(z) {
    this.z = z
  }
  get getZ() {
    /* get構文 */
    return this.z
  }
}
var hoo = new hooclass(20)
var val = hoo.getZ
console.log(val) /* 20が出力される */

クラス定義の中にgetという構文がある。このget構文を用いることで、オブジェクト作成後、get構文で指定したメソッドの返却値を取得できる。
また値を取得するget構文に対し、値を設定するset構文というものが存在する。

var hooclass = class {
  constructor(z) {
    this.z = z
  }
  get getZ() {
    return this.z
  }
  set setZ(z) {
    /* set構文 */
    this.z = z
  }
}
var hoo = new hooclass(20)
hoo.setZ = 100 /* プロパティに値を設定する */
var val = hoo.getZ
console.log(val) /* 100が出力される */

set構文で指定された上記コード中の valueOfZ() メソッドを使用すると、インスタンス作成後に、そのインスタンスのプロパティに値を設定することができる。
ここでははじめ、コンストラクタによりプロパティ z を 20 で初期化したインスタンスが、set構文で指定したメソッド valueOfZ に 100 を渡すことで、プロパティ z を 100 に再設定している。

継承

継承とは、クラス間に親子関係を作り出し、親のクラスが保有するメソッドやプロパティを使用できるようにするものである。
継承を行うには extends を利用する。

var hooclass = class {
  constructor(z) {
    this.z = z;
  }
  get getZ() {
    return this.z;
  }
  set setZ(z) {
    /* set構文 */
    this.z = z;
  }
};
/* hooclassの継承 */
var taaclass = class extends hooclass {
  constructor(z, num) {
    super(z); /* 親クラスのコンストラクタ */
    this.num = num;
  }
  calc() {
    return this.z * this.num;
  }
};

var taa = new taaclass(20, 3);
taa.setZ = 100; /* 親クラスのメソッドでプロパティに値を設定する */
console.log(taa.calc()); /* 300が出力される */

クラス作成時、上記コードのように extends + “継承したいクラス名” で親クラスを指定することができる。
継承する親クラスのプロパティを初期化するために、constructor には親クラスのコンストラクタを示す super() の引数に、初期化したい値を指定する必要がある。

静的メソッド

クラスのインスタンスではなく、クラスそのものから呼び出しを行う静的メソッドというものが存在する。

var hooclass = class {
  static writeDescription() {
    /* staticをつけることで静的メソッドを定義できる */
    return "これが静的メソッドです。";
  }
};
console.log(hooclass.writeDescription()); // 静的メソッド実行

メソッド名の前に static とある。これは、ここで定義するメソッドが静的メソッドであることを示す。静的メソッドはクラスのインスタンスではなく、クラスそのものから呼び出しを行うため、クラス名.静的メソッド名() のみで実行することができる。

inserted by FC2 system