プログラミング言語にはさまざまな種類が存在しますが、その中でもオブジェクト指向型と呼ばれる言語とそうでない言語があります。

JavaScriptは、ES6からクラスという手法が導入されたことにより、オブジェクト指向の機能が使えるようになりました。
オブジェクト指向は、より再利用性や可読性の高いコードを書くために重要な概念です。

そこで今回は、JavaScriptにおけるオブジェクト指向と、その機能であるクラスについて解説していきます。

オブジェクト指向

オブジェクト指向とは、プログラムを「モノ」として捉え、それを作成し操作していくための概念です。「オブジェクト」がここで言う「モノ」に該当し、データや処理の集まりのことを指します。
つまり、あるモノ(オブジェクト)と、モノが持っている機能をまとめて定義し、それを使用していく手法かつ考え方です。

例えば、家を建てるために必要な材料や手順をあらかじめ設計書として定義しておき、その設計書を使って実際に家を建てていきます。
既にあるデータを上手く使いながらも、足りない材料や工程は追加すれば良いので効率が良いわけです。

オブジェクト指向は、プログラミング言語全体で重要な概念ですが、実装するプログラムによって意味合いが少し異なるなど、”絶対これ”という正解はありません。
そのため、概念に執着しすぎずに、まずは使い慣れていくことも大切です。

クラス(Class)

クラス(Class)とは、モノそのものの設計書であり、設計するための構文です。

オブジェクト指向型の代表的な言語には、JavaやC#などがあります。これらはクラス構文を採用しています。
JavaScriptには、かつてはクラス構文が存在していませんでしたが、ES6から導入されたことにより、これらの言語と似たようにクラス構文が使えるようになりました。

補足ですが、ここで扱うクラス構文とCSSのclass属性とは全く関連性がありません。

クラスの使い方

ここからは、クラスの基本的な使い方を解説していきます。

クラス宣言

クラスを定義することをクラス宣言と呼びます。

class Classname {}

classの後に、オブジェクトを表す名前を定義します。頭文字は大文字になるため、注意してください。

クラス式

クラスを定義するには、クラス式を使うこともできます。式としてクラスを定義する方法です。

const Myclass = class{} // 名前無し
const Myclass = class Classname{} // 名前付き

クラス式の場合には、名前無しでも名前付きでも可能です。

コンストラクタ(Constructor)

コンストラクタ(Constructor)とは、クラスを定義する際にオブジェクトを初期化していくためのメソッドです。

class Classname {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
}

constructor()の中に引数を用意し、this.xthis.yにそれぞれの引数を代入します。
特殊な定義方法ですが、オブジェクトを初期化するために必須なメソッドとなります。

ここまではオブジェクトを初期化している段階ですが、これを使用して後から自分で指定した引数の値を設定できるようになります。

インスタンス化

実在するオブジェクトを作成するためには、クラスをインスタンス化する必要があります。
つまり、上記で定義したクラスから本来作成したいオブジェクトを作る工程です

インスタンス化には、new演算子を使います。

const instance = new Classname();

例えば、Rectangle(長方形)と言うクラスをインスタンス化し、実際の高さと幅を引数に入れてみます。

// クラスを定義
class Rectangle {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}

// クラスのインスタンス化
const instance = new Rectangle(15, 30);
console.log(instance.height); // 15
console.log(instance.width); // 30

インスタンス化されたことにより、new Rectangleの引数に入っている値が、クラス定義の際に初期化したコンストラクタの引数に渡されます。

さまざまな値を使う

クラスを定義する際には、コンストラクタメソッドでオブジェクトの初期化を用意すると説明しました。
オブジェクトの値には、文字列や数値だけでなく、関数やオブジェクト、配列などを指定することもできます。

以下は、ポケモンのキャラクターを作成する工程の例です。

// ポケモンクラスを定義
class Pokemon {
  constructor(props) { // オブジェクトを初期化
    this.type = props.type;
    this.name = props.name;
    this.technique = props.technique || [];
  }
}

// ポケモンクラスのインスタンス化、ピカチュウを作成
const pikachu = new Pokemon({
  type: 'でんきタイプ',
  name: 'ピカチュウ',
  technique: ['でんきショック', 'でんこうせっか', 'かみなり']
});

console.log(pikachu); // {name: "ピカチュウ", technique: ["でんきショック", "でんこうせっか", "かみなり"], type: "でんきタイプ"}
console.log(pikachu.type); // "でんきタイプ"
console.log(pikachu.name); // "ピカチュウ"
console.log(pikachu.technique); // ["でんきショック", "でんこうせっか", "かみなり"]

ポケモンのタイプ、名前、技をクラスで定義した後に、そのクラスを使いピカチュウというインスタンスを作成しています。
これでポケモンの設計書からピカチュウのみを作ることができました。

まとめ

今回は、オブジェクト指向とクラスの基本について解説しました。

クラスを使って再利用性の高いプログラムを書けるようになると、メンテナンスが楽になり、安全面や効率面に対して期待ができるようになります。

今後もクラスに関する実践的な使い方やメソッドについても取り上げていきますので、シリーズを通して学んでいきましょう。

合わせて読みたいクラスシリーズ

第1回:オブジェクト指向とクラス(当記事)
第2回:クラスとメソッド -インスタンスメソッド・アクセッサプロパティ
第3回:クラスとメソッド -staticメソッド
第4回:クラスの継承