JavaScriptのプロトタイプの継承パターン

提供:Dev Guides
移動先:案内検索

JavaScriptにはクラスは含まれていませんが、それでも強力なオブジェクト指向言語です。 JavaScriptのオブジェクト間の関係は、prototypeで実装されており、結果として得られるプロトタイプパターンはJavaScriptに非常に固有のものです。

ES6クラス構文の前は、継承のトピックは、他の言語から来た開発者にとってほとんど混乱していました。 これは、私の謙虚な意見では、JSが真にオブジェクト駆動型の言語であるためです。

これにより、JavaScriptオブジェクトの継承の概念を理解することが非常に困難になります。たとえば、クラスなしで同じプロパティを持つ新しいオブジェクトを作成するにはどうすればよいですか?。 この記事は、それと、このプロパティがJavaScriptの特定のオブジェクト指向パターンにどのように適用されるかを説明する試みです。

これまで見てきたように、JavaScriptのオブジェクトには、prototypeと呼ばれる共有プロパティを介して他のオブジェクトから直接継承する機能があり、prototypeを使用してJavaScriptオブジェクトに継承を実装する方法があります。

現在、この継承は、クラスベース言語で使用されている従来の継承ではなく、オブジェクト委任に匹敵するものです。 大まかに言うと、特定のプロパティがオブジェクトに見つからない場合は、そのプロトタイプで問題のプロパティの定義を確認します。

これが私が話していることを示すための簡単なスニペットです:

let Alligator = function(color) {
  this.color = color;
}

Alligator.prototype.introduce = function() {
 console.log('I am ' + this.color);
}

let Croc = function(color) {
  Alligator.call(this, color);
}

Croc.prototype = Object.create(Alligator.prototype)

let alligatorObj = new Alligator('green');
let crocObj = new Croc('yellow');

alligatorObj.introduce(); // I am green
crocObj.introduce(); // I am yellow

したがって、上記で起こったことはこれです-crocのインスタンスには、Crocprototypeにリンクするprototypeのコピーがあります。 AlligatorprototypeAlligator prototypeは、introduce()の定義を提供することができます。

これは、委任が意味するものであり、オブジェクト内のターゲットの動作(つまり、prototype)を検索します。 また、JavaScriptプロトタイプは複数のプロトタイプにリンクできるため、そのようにして複数の継承を行うこともできますが、実際にはそれはしばしば悪い考えです。

スニペットは、オブジェクト間コードがどのように見えるかの例です。 これは非常に原始的ですが、オブジェクト間でのプロパティとメソッドの直接転送を容易にします。 これはJavaScriptの設計に組み込まれています。 クラスのシンタックスシュガーまたはコンストラクターは、これを単にラッパーにして、古典的なOOPのように感じさせます。

ほとんどの場合、プロトタイプパターンは非常にシンプルで実装が簡単です。 なんで? オブジェクトとクラスの古典的な理解のために、コンストラクター関数がインスタンスを作成することを期待しています。 JavaScriptでは、次のように任意の関数をコンストラクターにすることができます。

function Alligator(color) {
 This.color = color;
}

Let alligator = new Alligator('purple');

newキーワードを関数呼び出しの前に付けるだけで、オブジェクトができます。 newキーワードは、this(新しいコンテキスト)を関数呼び出しにバインドすることにより、コンストラクターとしてAlligator()関数を呼び出すだけです。 JavaScriptで古典的なオブジェクトパターンを機能させるために、単に邪魔にならないように感じます。 これと比較すると、プロトタイプパターンは直感的に感じられます。 また、慣例により、新しいオブジェクトのコンストラクターとして使用することを目的とした関数は大文字で始める必要があります。そうしないと、newキーワードを使用する場所を知るのが非常に混乱する可能性があります。