IT・WEB・ゲーム業界の転職に強いR-Stone

転職コラム

Javascriptのclassとは?基本的な書き方や活用方法をわかりやすく説明

オブジェクト指向プログラミングの概念をJavaScriptで実現するclassを、基礎から応用まで詳しく解説します。classの定義方法、constructorの役割、メソッドの実装など、基本的な書き方を学びます。

さらに、クラスの拡張、ゲッターとセッターの実装、プライベートフィールドなど、実践的な活用方法も紹介します。

本記事を通じて、classを使いこなし、より効率的で保守性の高いコードを書く技術を身につけましょう。

JavaScriptのclassの定義

classを使うと、オブジェクトの設計図のようなものを作成でき、同じ構造や振る舞いを持つオブジェクトを簡単に作成できるため、コードの構造化や再利用性の向上が図れます。

JavaScriptのclassは、オブジェクト指向プログラミングを実現する構文としてES6(ECMAScript 2015)で導入され、2017年3月以降はすべての主要ブラウザで利用できるようになりました。

classは、JavaScriptの既存のプロトタイプベースの継承モデルをもとにしていますが、より直感的で使いやすい構文です。

classの特徴

JavaScriptのclassは、多くのプログラミング言語と同様に、classキーワードを使用して宣言します。例えば、class MyClass {}のように記述します。

クラス内ではプロパティ(データ)とメソッド(関数)を定義でき、オブジェクトの構造と振る舞いを一箇所にまとめる、カプセル化ができます。

また、関数宣言と異なり、class宣言は巻き上げ(ホイスティング)がないため、クラスを使用する前に必ず宣言する必要があります。

classでできること

classを使うと、定義したクラスからnewキーワードを使ってオブジェクトを生成できます。

また、extendsキーワードにより、他のクラスを継承・拡張したり、オーバーライドしたりできます。

staticキーワードでは、インスタンス化せず直接呼び出せる静的メソッドも定義できます。

class構文の基本的な書き方

JavaScriptのclass構文の基本的な書き方をご紹介します。

class PlayerCharacter { // プレイヤーキャラクタークラス

  constructor(name, job) {  // コンストラクタ

    this.name = name;     // 名前を設定 「this.」は「このインスタンス」を表す

    this.job = job;       // 職業を設定

    this.hp = 100;        // HPを100に設定

    this.str = 10;        // 筋力を10に設定

    this.int = 10;        // 知力を10に設定

  }

 

  displayStatus() { // ステータスを表示するメソッド

    console.log(`名前: ${this.name}, 職業: ${this.job}, HP: ${this.hp}, 筋力: ${this.str}, 知力: ${this.int}`);

  }

 

  damage(d) {   // ダメージを与えるメソッド

    this.hp -= d; // HPからダメージ分を減算

    if (this.hp < 1) console.log(`${this.name} はしんでしまった.`);

  }

}

クラス名は大文字で始めるのが一般的です。

constructorはクラスのインスタンスを作成する際に呼び出される特別なメソッドで、メソッドはクラス内で定義された関数です。

クラスを使用するには、newキーワードでインスタンスを作成します。

const player = new PlayerCharacter(‘Brave’, ‘戦士’);

player.displayStatus(); // ドット(.)を使いメソッドにアクセスできます

// 名前: Brave, 職業: 戦士, HP: 100, MP: 50, 筋力: 10, 知力: 10

クラス式について

クラス式は、クラスを定義する別の方法です。クラス宣言との主な違いは、変数に代入できる点です。

クラス式には、名前付きと匿名の2種類があります。

const NamedClass = class ClassName {    // 名前付きクラス式

  // クラスの内容

};

 

const AnonymousClass = class// 匿名クラス式

  // クラスの内容

};

クラス式は、クラスを動的に生成したり、関数の引数として渡したりする場合に便利です。

// 条件に応じて異なるクラスを生成する例

const MyClass = condition ? class A { /* … */ } : class B { /* … */ };

また、クラス式は即時実行できます。

const instance = new (class {

  constructor(name) {

    this.name = name;

  }

  sayHello() {

    console.log(`Hello, ${this.name}!`);

  }

})(“John”);

 

instance.sayHello(); // “Hello, John!”

classのconstructorについて

constructorは、クラスのインスタンスを作成する際に自動的に呼び出される特別なメソッドです。主な役割は、インスタンスの初期化です。

constructorはクラス内で1つのみ定義でき(省略可能)ます。

class Car {

  constructor(make, model, year) {

    this.make = make;   // thisキーワードを使い、インスタンスのプロパティを設定

    this.model = model;

    this.year = year;

    this.speed = 0; // 初期値の設定

  }

 

  accelerate(amount) {  // 速度を上げるメソッド

    this.speed += amount;

  }

}

 

const myCar = new Car(“Toyota”, “カローラ”, 2024);

console.log(myCar.make); // “Toyota”

myCar.accelerate(50);

console.log(myCar.speed); // 50

constructorでは、インスタンス作成時にプロパティを初期化し、クラスの使用準備を整えることができます。

classの活用方法

classの主な活用方法を見ていきましょう。

継承を使ったクラスの拡張

継承を使うと、既存のクラスをもとに新しいクラスを作成できます。

 

class Animal {  // 動物クラス

  constructor(name) {

    this.name = name; // 名前プロパティを設定

  }

 

  speak() { // 鳴く機能

    console.log(`${this.name} は鳴く.`); // 動物の鳴き声を出力

  }

}

 

class Dog extends Animal {  // 犬クラスを定義(Animalクラスを継承)

  speak() { // 鳴く機能をオーバーライド

    console.log(`${this.name} は吠える.`); // 犬の鳴き声を出力

    // super.speak(); // 親クラスのspeakメソッドはsuperキーワードで参照可能

  }

}

 

const dog = new Dog(‘ポチ’);

// 犬クラスがオーバーライドした speak() メソッドを呼ぶ例

dog.speak(); // ポチ は吠える.

継承により、コードの再利用性が高まり、開発効率が向上します。

ゲッターとセッターの実装

ゲッター・セッターを使うと、プロパティへのアクセスを制御でき、データの整合性を保ちつつ、使いやすいインターフェースを提供できます。

class Temperature {

  constructor(celsius) {

    this._celsius = celsius;    // クラス内部では摂氏温度を扱う

  }

 

  get fahrenheit() {    // 華氏温度を取得するゲッターの定義

    return this._celsius * 9 / 5 + 32;

  }

 

  set fahrenheit(value) {   // 華氏で温度を設定するセッターの定義

    this._celsius = (value 32) * 5 / 9;

  }

}

 

const temp = new Temperature(25);   // 25℃(77F)に初期化

console.log(temp.fahrenheit); // 77 // ゲッターを使用

temp.fahrenheit = 86;   // 86F(30℃)に設定. セッター利用

console.log(temp._celsius); // 30

プライベートプロパティとメソッド

プロパティやメソッド名の頭に#を付けるとクラス外からアクセスできない要素を定義できます。

外部からの不適切な変更を防止し、クラス内部の変更が外部に与える影響を限定でき、コードの保守性を高めます。

class Counter {

  #count = 0; // プライベートプロパティ

 

  #increment() { // プライベートメソッド

    this.#count++;

  }

 

  getCount() {

    this.#increment();

    return this.#count;

  }

}

 

const counter = new Counter();

console.log(counter.getCount()); // 1

// console.log(counter.#count); // エラー。#countにはアクセスできない。

ミックスイン(mix-in)

ミックスインは、クラスに追加の機能や振る舞いを提供する再利用可能なコード部品で、JavaScriptではObject.assignを使って実装できます。

const LoggerMixin = {   // ログ機能ミックスインの定義

  log(message) {

    console.log(`[${this.constructor.name}]: ${message}`);

  }

};

 

const TimestampMixin = {    // タイムスタンプ機能ミックスインの定義

  getTimestamp() {

    return new Date().toISOString();

  }

};

 

class User {    // Userクラス

  constructor(name) {

    this.name = name;

  }

}

 

// Object.assignを使ってUserクラスへミックスインを適用

Object.assign(User.prototype, LoggerMixin, TimestampMixin);

 

const user = new User(“Alice”);

user.log(“ログインしました”); // [User]: ログインしました

console.log(user.getTimestamp()); // 2024-09-29T12:34:56.789Z

ミックスインを使うと、既存のクラス階層を変更せずに機能を追加でき、柔軟なコード設計が可能ですが、節度を持ってご利用ください。

まとめ

JavaScriptのclassは、オブジェクトの設計図として機能し、コードの再利用性を高めます。基本的な書き方から応用まで、classの特徴を理解すると、より効率的なコーディングが可能になります。

classを活用して、より洗練されたJavaScriptプログラムを書いてみましょう。