JavaScriptのclassとprototypeの違いは何ですか?

JavaScriptにおけるクラスとプロトタイプの違い

JavaScriptにおけるクラスとプロトタイプの違い

JavaScriptは、しばしば「プロトタイプベースのオブジェクト指向プログラミング言語」と表現されます。しかし、ES2015でclass構文が導入されてから、伝統的なクラスベースのオブジェクト指向言語と混同されるケースも少なくありません。そこで、本稿ではJavaScriptにおけるクラスとプロトタイプの違いについて、具体的なコード例を交えながら解説していきます。

クラスベースとプロトタイプベースの根本的な違い

クラスベースとプロトタイプベースの根本的な違いは「ユーザ定義型のデータ構造が静的か動的か」という点にあると考えています。 つまりクラスは静的なユーザ定義型データ構造、プロトタイプは動的なユーザ定義型データ構造ということです。

特徴 クラスベース プロトタイプベース
データ構造 静的 動的
継承方法 クラスベース継承 プロトタイプチェーン
オブジェクト生成 クラスを元にインスタンス化 既存オブジェクトの複製

クラスベースにおける継承

Javaなどのクラスベースの言語では、クラスを定義し、そのクラスを元にオブジェクトを生成します。継承は、既存のクラスを拡張して新しいクラスを作成するメカニズムです。


    class Animal {
      constructor(name) {
        this.name = name;
      }

      speak() {
        console.log(`${this.name}は鳴きます`);
      }
    }

    class Dog extends Animal {
      speak() {
        console.log(`${this.name}はワンワン吠えます`);
      }
    }

    const dog = new Dog('ポチ');
    dog.speak(); // 出力: ポチはワンワン吠えます
  

プロトタイプベースにおける継承

JavaScriptでは、すべてのオブジェクトは内部に[[Prototype]]という隠しプロパティを持ち、他のオブジェクトを参照しています。この参照関係を「プロトタイプチェーン」と呼びます。オブジェクトは、自身に定義されていないプロパティやメソッドを、プロトタイプチェーンを通じて探索します。


    function Animal(name) {
      this.name = name;
    }

    Animal.prototype.speak = function() {
      console.log(`${this.name}は鳴きます`);
    };

    function Dog(name) {
      Animal.call(this, name);
    }

    Dog.prototype = Object.create(Animal.prototype);
    Dog.prototype.constructor = Dog;

    Dog.prototype.speak = function() {
      console.log(`${this.name}はワンワン吠えます`);
    };

    const dog = new Dog('ポチ');
    dog.speak(); // 出力: ポチはワンワン吠えます
  

クラスとプロトタイプの使い分け

ES2015でクラス構文が導入されたことで、JavaScriptでも従来のクラスベースに近い記述が可能になりました。しかし、内部的にはプロトタイプベースの仕組みで動作している点は変わりません。基本的には、クラス構文を用いることで、より簡潔で可読性の高いコードを記述することができます。一方、プロトタイプベースの理解を深めることで、JavaScriptの柔軟なオブジェクト指向プログラミングを最大限に活用することができます。

参考文献

関連QA

Q1: JavaScriptではクラスとプロトタイプのどちらを使うべきですか?

A1: 基本的には可読性が高く、理解しやすいクラス構文を利用することを推奨します。ただし、JavaScriptの柔軟なオブジェクト操作を行う場合は、プロトタイプベースの仕組みを理解しておく必要があります。

Q2: プロトタイプチェーンとは何ですか?

A2: JavaScriptのオブジェクトは、内部に[[Prototype]]という隠しプロパティを持ち、他のオブジェクトを参照しています。この参照関係を「プロトタイプチェーン」と呼び、オブジェクトは自身に定義されていないプロパティやメソッドを、このプロトタイプチェーンを通じて探索します。

Q3: クラスベースとプロトタイプベースのどちらが優れているのですか?

A3: どちらが良い悪いではなく、それぞれに特徴があります。クラスベースは理解しやすく、構造的なプログラムに適しています。一方、プロトタイプベースは柔軟性が高く、動的なプログラムに適しています。

その他の参考記事:JavaScript テスト プロトタイプ