JavaScriptにおけるクラス

JavaScriptにおけるクラス

この記事ではJavaScriptにおけるクラスについて説明します。

YouTube Video

JavaScriptにおけるクラス

JavaScriptにおけるクラスは、オブジェクト指向プログラミングの概念を取り入れたもので、オブジェクトの設計図として機能します。クラスを使うことで、オブジェクトのプロパティメソッドを簡潔に定義でき、再利用性やコードの整理が向上します。JavaScriptではES6からクラス構文が導入されました。

クラスの定義

クラスはclassキーワードを使って定義され、通常はコンストラクタと呼ばれるメソッドで初期化されます。

 1class Person {
 2    // Constructor method (called when the class is instantiated)
 3    constructor(name, age) {
 4        this.name = name; // Property definition
 5        this.age = age;
 6    }
 7
 8    // Method definition
 9    greet() {
10        return `Hello, my name is ${this.name}`;
11    }
12}
13
14// Instantiation of the class
15const alice = new Person("Alice", 25);
16console.log(alice.greet()); // Hello, my name is Alice
  • class Personクラスを定義しています。
  • constructorは、オブジェクトが生成された際に自動的に呼び出される特殊なメソッド(コンストラクタ)です。
  • thisキーワードは、クラス内でそのクラスのインスタンス(オブジェクト)を指します。

クラスのプロパティとメソッド

クラスにはプロパティメソッドが定義できます。プロパティはオブジェクトの属性を表し、メソッドはオブジェクトが持つ機能を表します。

 1class Car {
 2    constructor(brand, model) {
 3        this.brand = brand;
 4        this.model = model;
 5    }
 6
 7    // Method definition
 8    drive() {
 9        console.log(`Driving a ${this.brand} ${this.model}`);
10    }
11}
12
13const car1 = new Car("Toyota", "Corolla");
14car1.drive(); // Driving a Toyota Corolla

この例では、brandmodelプロパティとdriveメソッドを持つCarクラスが宣言されています。

クラスの継承

クラスは他のクラスから継承することができます。継承を使うことで、既存のクラスを基に新しいクラスを作成し、そのクラスに追加の機能を付け加えることができます。

 1class Animal {
 2    constructor(name) {
 3        this.name = name;
 4    }
 5
 6    speak() {
 7        console.log(`${this.name} makes a noise`);
 8    }
 9}
10
11// Inherit from the Animal class
12class Dog extends Animal {
13    constructor(name, breed) {
14        super(name); // Call the constructor of the parent class (Animal)
15        this.breed = breed;
16    }
17
18    // Override the method
19    speak() {
20        console.log(`${this.name} barks`);
21    }
22}
23
24const dog = new Dog("Rex", "German Shepherd");
25dog.speak(); // Rex barks

この例では、DogクラスはAnimalクラスを継承しています。

  • extendsキーワードを使ってAnimalクラスを継承します。
  • Dogクラスのコンストラクタ内のsuper()は親クラスのコンストラクタを呼び出すために使われます。これにより、親クラスの初期化処理を引き継ぐことができます。
  • 継承したクラス内で、親クラスのメソッドをオーバーライド(上書き)できます。この例では、"Rex makes a noise"ではなく、"Rex barks"と表示されます。

スタティックメソッド

クラス内にスタティックメソッドを定義すると、そのメソッドはクラス自体に紐づきます。スタティックメソッドはインスタンス化することなく呼び出せます。

1class MathUtils {
2    // Static method
3    static add(a, b) {
4        return a + b;
5    }
6}
7
8console.log(MathUtils.add(5, 10)); // 15

この例では、MathUtilsクラスにスタティックメソッドaddを定義しています。

  • staticキーワードを使ってスタティックメソッドを定義します。
  • スタティックメソッドはクラスインスタンスには属さず、クラス自体から直接呼び出されます。

ゲッター(getter)とセッター(setter)

クラス内でゲッターセッターを定義することで、プロパティの取得と設定をカプセル化できます。

 1class Rectangle {
 2    constructor(width, height) {
 3        this.width = width;
 4        this.height = height;
 5    }
 6
 7    // Getter
 8    get area() {
 9        return this.width * this.height;
10    }
11
12    // Setter
13    set widthValue(newWidth) {
14        this.width = newWidth;
15    }
16}
17
18const rect = new Rectangle(10, 20);
19console.log(rect.area); // 200
20
21rect.widthValue = 15;
22console.log(rect.area); // 300

この例では、RectangleクラスにareaゲッターとwidthValueセッターを定義しています。

  • ゲッターget)はプロパティの値を取得する際に呼び出されます。
  • セッターset)はプロパティの値を設定する際に呼び出されます。

クラスのシンタックスシュガー

JavaScriptのクラス構文は、内部的にはコンストラクタ関数プロトタイプを使って実現されています。クラス構文はこれらをより簡潔に書くためのシンタックスシュガーです。

 1// Example without using class syntax
 2function Person(name, age) {
 3    this.name = name;
 4    this.age = age;
 5}
 6
 7Person.prototype.greet = function() {
 8    return `Hello, my name is ${this.name}`;
 9};
10
11const person = new Person("Alice", 25);
12console.log(person.greet()); // Hello, my name is Alice

この例では、コンストラクタ関数としてPerson関数を定義し、プロトタイプを使ってgreetメソッドを定義しています。

thisの扱い

クラス内のthisキーワードは、そのクラスのインスタンスを指します。しかし、クラスメソッドの中でthisを扱う場合、スコープによって挙動が異なることに注意が必要です。特にメソッドをコールバック関数として使うときに問題が発生することがあります。

 1class Counter {
 2    constructor() {
 3        this.count = 0;
 4    }
 5
 6    increment() {
 7        this.count++;
 8        console.log(this.count);
 9    }
10}
11
12const counter = new Counter();
13setTimeout(counter.increment, 1000); // NaN
14// NaN, since this.count is undefined, it becomes NaN after incrementing.

この場合、setTimeoutのコールバックとして渡されるときにthisの指す対象が変わってしまいます。この問題を避けるにはbindメソッドを使ってthisを固定するか、アロー関数を使うことが推奨されます。

 1class Counter {
 2    constructor() {
 3        this.count = 0;
 4    }
 5
 6    increment() {
 7        this.count++;
 8        console.log(this.count);
 9    }
10}
11
12const counter = new Counter();
13
14// When using bind
15setTimeout(counter.increment.bind(counter), 1000);
16
17// When using an arrow function
18setTimeout(() => counter.increment(), 2000);

まとめ

  • クラスはオブジェクトを作成するための設計図として使われ、プロパティやメソッドを定義できます。
  • 継承を使ってクラスを拡張し、オブジェクト指向の概念を活用できます。
  • スタティックメソッドはクラス自体に属し、インスタンスを作成せずに使用できます。
  • ゲッターセッターを使ってプロパティのカプセル化が可能です。
  • JavaScriptのクラス構文はシンタックスシュガーであり、内部的にはプロトタイプベースの継承を利用しています。

クラスを使うことで、オブジェクト指向プログラミングをより自然に扱えるようになり、コードの再利用性や保守性を向上させることができます。

YouTubeチャンネルでは、Visual Studio Codeを用いて上記の記事を見ながら確認できます。 ぜひYouTubeチャンネルもご覧ください。

YouTube Video