JavaScriptでclassを追加する方法を理解しよう

class構文とは何か?

他のプログラミング言語同様、JavaScriptにもclassという関数のまとまりを定義する手法が用意されています。正確には擬似的に実現しているだけなのですが、ここについて詳しく知っておく必要はないでしょう。

classは変数や関数の箱

classは「引数として受け取ったデータを使う処理をまとめてパッケージにした関数がまとまった箱」です。

プログラムの世界では「複数のデータに同じ処理」を行うことがあります。

いちいちコードを書くのは賢くないため、繰り返し使える様に、汎用化できるコードは汎用化させるのが一般的です。

classはこのような「汎用化パッケージ作成機能」と捉えても良いでしょう。

インスタンス化

これまで説明したClassとはあくまで「機能がまとめてある箱」です。それをそのまま処理の実行に使うわけではありません。これは仕様の決まりです。

class宣言で定義したクラスを実際のデータとして使うには、new 演算子を用いて「new クラス名(【引数】,【引数】)」とします。

JavaScript
//Classのインスタンス化(Class内の処理の元になるデータを引数として渡す)
const targetInstance = new targetClass('User A', 1);

この作業を「インスタンス化」といいます。

インスタンス化することで、クラスからデータをコピーした後に、【引数】のデータをクラスの構成要素(コンストラクター・メソッド)に反映した状態の物を取得できます。

ただし、後述する「スタティックメソッド」と呼ばれるクラスの構成要素だけは、インスタンス化を経由せずに読み込む必要があります。

KAZU
KAZU

インスタンス変数の使用例については後述しています。

Classの作成方法

classはJavaScriptの中でも理解が難しい概念です。仕様の説明の前に先に完成コードの例を紹介しておきます。

JavaScript
const targetText = document.getElementById( 'targetText' );
const targetText2 = document.getElementById( 'targetText2' );
const targetText3 = document.getElementById( 'targetText3' );

//クラスを定義処理の塊
class targetClass {
  constructor(value1,value2) {
		//class内で変数を定義
		this.targetVariable1 = value1;
		//class内で変数を定義
		this.targetVariable2 = value2;
		//class内で変数を用いた処理
		targetText.textContent = `${this.targetVariable1}:${this.targetVariable2}`;
  }
	//class内で関数を定義
	targetMethod() {
		targetText2.textContent = `私はメソッドです。受け取った引数は「${this.targetVariable1}」と「${this.targetVariable2}」だよ。`;
	}
	
	//class内のスタティックメソッドを定義
	static targetmethodStatic() {
		targetText3.textContent = `私はスタティックメソッドです。受け取った引数は「${this.targetVariable1}」と「${this.targetVariable2}」だよ。要するに私はスタティックメソッドなので、Constroctorの値は受け取らないよ。引数入れても無駄`;
	}
}

//Classのインスタンス化(Class内の処理の元になるデータを引数として渡す)
const targetInstance = new targetClass('User A', 1);

//targetInstanceの中のtargetmethodを実行
targetInstance.targetMethod();

//Staticメソッドを実行
targetClass.targetmethodStatic('User A', 1);

では解説に入ります。

クラスを宣言

Classの中身を作成する前に、まずはClassを宣言する必要があります。

クラスは、classキーワードを用いて宣言します。クラスの名前は任意ですが、大文字からキャメルケースで定義するのが通例です。

構文意味
class クラス名 {}クラス宣言
JavaScriptにおけるClass宣言
JavaScript
class targetClass {};

classの構成要素

classの宣言が完了したら、classの構成要素を考えます。

名称構文役割
コンストラクターconstructorクラスが使用された時に必ず実行されるメソッド
クラスメソッド(クラス内の関数)メソッド名(){}クラス内の関数をクラスメソッドという。定義時にfunctionと付けない点が異なる。
クラス変数this.変数=値メソッドの様に自由に定義できるわけではなく、constructor内において、インスタンス化時に渡される引数をクラス内で活用するために用いられる。
スタティックメソッドstatic メソッド名{}クラスをインスタンス化することなく、直接実行することができるメソッド。インスタンス化を経由しないので、constructorの処理も実行されない。
Class構文内で使える構成要素

コンストラクターの作成

constructor()文はクラスがインスタンス化された時に必ず実行される処理を記載します。一般的に下記の用途で使われます。

  • 【引数】をクラス内のメソッドで扱える様にするためにクラス内変数に格納
  • インスタンス化時に必ず行う処理の実行

constructor()は1つしか記述できません。基本形は以下の通りです。

JavaScript
//クラスを定義処理の塊
class targetClass {
  constructor() {
    【処理】
  }
}

クラスの初期化時に外部から初期値を渡すこともできます。

インスタンス化時に【引数】を渡している場合は、下記の様なコードになるでしょう。

JavaScript
//クラスを定義処理の塊
class targetClass {
  constructor(【引数1】,【引数2】) {
		//class内で変数を定義
		this.targetVariable1 = 【引数1】;
		//class内で変数を定義
		this.targetVariable2 = 【引数2】;
		//class内で変数を用いた処理
		targetText.textContent = `${this.targetVariable1}:${this.targetVariable2}`;
  }
}

クラス変数

先ほどのコンストラクター内で変数を使ったサンプルコードを紹介しています。下記の部分です。

構文意味
this.変数名 = 値クラス変数を定義
クラス変数の仕様
JavaScript
//class内で変数を定義
this.targetVariable1 = value1;
//class内で変数を定義
this.targetVariable2 = value2;

クラスに属する変数は「クラス変数」・「メンバーフィールド」・「メンバー変数」なんて言い方をします。

クラス変数は下記の様な使い方をします。

  1. クラスの【引数】としてデータをいれる
  2. constructor()内で【引数】をクラス変数に代入する
  3. 代入されたクラス変数をクラスメソッドで使う
注意

クラス変数はクラスメソッドでは利用可能ですが、スティックメソッド内では利用できません。

例えば、クラスtargetClassに対してtargetFieldというクラス変数を定義するには次の様にconstructor()内に「this.【変数名】」と記述します。

thisとはクラス自身のことを挿します。慣れないうちは「letやconstを記述しない点に注意」が必要です。

具体的には、下記の様な書き方になります。

JavaScript
class targetClass {
  constructor(value1,value2) {
		//class内で変数を定義
		this.targetVariable1 = value1;
		//class内で変数を定義
		this.targetVariable2 = value2;
		//class内で変数を用いた処理
		targetText.textContent = `${this.targetVariable1}:${this.targetVariable2}`;
  }
}

また、クラス変数には、【引数】の値を与えるのではなく、初期値を代入することも可能です。代入しない場合はundefinedになります。

JavaScript
class targetClass {
  constructor(value1,value2) {
		//class内で変数を定義
		this.targetVariable1 = 'User A';
		//class内で変数を定義
		this.targetVariable2 = 100;
		//class内で変数を用いた処理
		targetText.textContent = `${this.targetVariable1}:${this.targetVariable2}`;
  }
}

クラスメソッドを定義する

クラスに属する関数は「クラスメソッド」や「メンバー関数」と呼びます。

構文意味
メソッド名(){処理内容}クラスメソッドを定義
クラスメソッドの仕様

例えば、クラスtargetClassに対して、targetMethodというクラスメソッドを定義するには下記の様に書きます。

この時、「通常の関数宣言の様にfunctionを定義しない」様に気を付けてください。「クラスメソッド」は幾つでも定義できます。

これまでのサンプルコードにクラスメソッドを追加すると下記の様になります。

JavaScript
//クラスを定義処理の塊
class targetClass {
  constructor(value1,value2) {
		//class内で変数を定義
		this.targetVariable1 = value1;
		//class内で変数を定義
		this.targetVariable2 = value2;
		//class内で変数を用いた処理
		targetText.textContent = `${this.targetVariable1}:${this.targetVariable2}`;
  }
	//クラスメソッド
	targetMethod() {
		targetText2.textContent = `私はメソッドです。受け取った引数は「${this.targetVariable1}」と「${this.targetVariable2}」だよ。`;
	}
}

スタティックメソッド

クラスをインスタンス化することなく呼び出すことができるメソッドを「静的メソッド」・「スタティックメソッド」といいます。

構文意味
static メソッド名(){処理内容}スタティックメソッドを定義
スタティックメソッドの仕様

スタティックメソッドは、次の様にstatic宣言により定義します。これまでのコードにスタティックメソッドを含めた物を紹介します。

スタティックメソッドは、コンストラクターを経由しないのでコンストラクターを経由する様なインスタンス化されたクラスに代入される【引数】は受け取ることができませんが、スタティックメソッド自体に【引数】を指定して、スタティックメソッド内で使うことが可能です。

下記のサンプルコードでは「firstName,lastName」がそれにあたります。

JavaScript
//クラスを定義処理の塊
class targetClass {
  constructor(value1,value2) {
		//class内で変数を定義
		this.targetVariable1 = value1;
		//class内で変数を定義
		this.targetVariable2 = value2;
		//class内で変数を用いた処理
		targetText.textContent = `${this.targetVariable1}:${this.targetVariable2}`;
  }
	//class内で関数を定義
	targetMethod() {
		targetText2.textContent = `私はメソッドです。受け取った引数は「${this.targetVariable1}」と「${this.targetVariable2}」だよ。`;
	}
	
	//class内のスタティックメソッドを定義
	static targetmethodStatic(firstName,lastName) {
		targetText3.textContent = `私は「${firstName}${lastName}です。スタティックメソッドの引数はこの様に受け取れる。だけクラスの方で受け取った引数は「${this.targetVariable1}」と「${this.targetVariable2}」だよ。要するに私はスタティックメソッドなので、Constroctorの値は受け取らないよ。引数入れても無駄`;
	}
}

使い所は下記の条件を満たしている時が推測されます。

  • 汎用的に使いたい関数のメソッド化
  • クラスの【引数(クラス変数)】に依存せず、クラス内でも完全に独立している場合

クラスをインスタンス化して利用する

class宣言で定義したクラスを実際のデータとして使うには、new 演算子を用いて「new クラス名(【引数】,【引数】)」とします。

構文意味
new クラス名(【引数1】,【引数2】,…)クラスをインスタンス化する
クラスのインスタンス化の仕様

これまで紹介したコードを合わせて作成されたクラスは下記の様になりました。

JavaScript
//クラスを定義処理の塊
class targetClass {
  constructor(value1,value2) {
		//class内で変数を定義
		this.targetVariable1 = value1;
		//class内で変数を定義
		this.targetVariable2 = value2;
		//class内で変数を用いた処理
		targetText.textContent = `${this.targetVariable1}:${this.targetVariable2}`;
  }
	//class内で関数を定義
	targetMethod() {
		targetText2.textContent = `私はメソッドです。受け取った引数は「${this.targetVariable1}」と「${this.targetVariable2}」だよ。`;
	}
	
	//class内のスタティックメソッドを定義
	static targetmethodStatic(firstName,lastName) {
		targetText3.textContent = `私は「${firstName}${lastName}です。スタティックメソッドの引数はこの様に受け取れる。だけクラスの方で受け取った引数は「${this.targetVariable1}」と「${this.targetVariable2}」だよ。要するに私はスタティックメソッドなので、Constroctorの値は受け取らないよ。引数入れても無駄`;
	}
}

では、これをインスタンス化させます。

インスタンス化

JavaScript
//Classのインスタンス化(Class内の処理の元になるデータを引数として渡す)
const targetInstance = new targetClass('User A', 1);

クラスメソッドを利用

インスタンス化すると、クラスメソッドを利用が可能です。クラスメソッドは下記の様な形式で使うことができます。

JavaScript
//targetInstanceの中のtargetmethodを実行
targetInstance.targetMethod();

完成系

スタティックメソッドは「インスタンス化せずに呼び出す」メソッドです。これまでの説明の中で作成したスタティックメソッドを呼び出すには、下記の様に書きます。

JavaScript
//Staticメソッドを実行
targetClass.targetmethodStatic('Sample', 'Person');

完成系

ここまでで、Classの作成と使い方までを述べてきました。まとめとして、これまで紹介したサンプルコードの完成形を表示しておきます。

サンプルコードは、クラス内のでデータの処理を行い、その結果をHTML上に出力する物です。

Output
クラス定義(Constructor)
クラス定義(targetMethod)
クラス定義(staticTargetMethod)
Pug
table.table
			tbody
				tr
					th クラス定義(Constructor)
					td#targetText
				tr
					th クラス定義(targetMethod)
					td#targetText2
				tr
					th クラス定義(staticTargetMethod)
					td#targetText3
JavaScript
const targetText = document.getElementById( 'targetText' );
const targetText2 = document.getElementById( 'targetText2' );
const targetText3 = document.getElementById( 'targetText3' );

//クラスを定義処理の塊
class targetClass {
  constructor(value1,value2) {
		//class内で変数を定義
		this.targetVariable1 = value1;
		//class内で変数を定義
		this.targetVariable2 = value2;
		//class内で変数を用いた処理
		targetText.textContent = `${this.targetVariable1}:${this.targetVariable2}`;
  }
	//class内で関数を定義
	targetMethod() {
		targetText2.textContent = `私はメソッドです。受け取った引数は「${this.targetVariable1}」と「${this.targetVariable2}」だよ。`;
	}
	
	//class内のスタティックメソッドを定義
	static targetmethodStatic(firstName,lastName) {
		targetText3.textContent = `私は「${firstName}${lastName}」です。スタティックメソッドの引数はこの様に受け取れる。だけどクラスの方で受け取った引数は「${this.targetVariable1}」と「${this.targetVariable2}」だよ。要するに私はスタティックメソッドなので、Constroctorの値は受け取らないよ。引数入れても無駄`;
	}
}

//Classのインスタンス化(Class内の処理の元になるデータを引数として渡す)
const targetInstance = new targetClass('User A', 1);

//targetInstanceの中のtargetmethodを実行
targetInstance.targetMethod();

//Staticメソッドを実行
targetClass.targetmethodStatic('Sample', 'Person');
インストラクター