あなたが StackOverflow のかなり新しいメンバーのように見えるので落胆させたくはありませんが、少し顔を合わせて、JavaScript で古典的な継承を実装しようとするのは本当に悪い考えだと言わなければなりません。 .
注: JavaScript で古典的な継承を実装するのは悪い考えだと言うとき、JavaScript で実際のクラス、インターフェイス、アクセス修飾子などをシミュレートしようとするのは悪い考えだということです。それにもかかわらず、JavaScript の設計パターンとしての古典的な継承は、プロトタイプの継承 (最大最小クラスなど) の構文糖衣にすぎないため、便利です。私はコードでこのデザイン パターンを常に使用しています ( a la Augment )。
JavaScript は、プロトタイプのオブジェクト指向プログラミング言語です。古典的なオブジェクト指向プログラミング言語ではありません。確かに、 JavaScript の上に従来の継承を実装することはできますが、その前に次のことを念頭に置いてください。
- あなたは言語の精神に逆らっています。つまり、問題に直面することになります。多くの問題 - パフォーマンス、可読性、保守性など。
- クラスは必要ありません。トーマス、あなたはクラスが必要だと本当に信じていることを知っていますが、これについては私を信頼してください. あなたはそうしない。
念のため、この質問に対して 2 つの回答を提供します。最初のものは、JavaScript で古典的な継承を行う方法を示します。2 つ目 (これをお勧めします) は、プロトタイプの継承を受け入れることを教えてくれます。
JavaScript における古典的な継承
ほとんどのプログラマーは、JavaScript で古典的な継承を実装しようとすることから始めます。Douglas Crockford のような JavaScript の達人でさえ、JavaScript で古典的な継承を実装しようとしました。私も JavaScript で古典的な継承を実装しようとしました。
まず、 Clockworkというライブラリを作成してから、augmentを作成しました。ただし、JavaScript の精神に反するため、これらのライブラリを使用することはお勧めしません。実は、これらの古典的な継承ライブラリを作成したとき、私はまだアマチュアの JavaScript プログラマーでした。
私がこれに言及する唯一の理由は、ある時点で誰もがアマチュアであるからです。JavaScript で古典的な継承パターンを使用しないことを望んでいますが、プロトタイプの継承がなぜ重要なのかを理解することはまだ期待できません。
何度か転ぶことなく自転車に乗る方法を学ぶことはできません。プロトタイプの継承に関しては、まだ学習段階にあると思います。古典的な継承の必要性は、自転車の補助輪のようなものです。
それでも、補助輪は重要です。必要に応じて、JavaScript でコードをより快適に記述できるようにする従来の継承ライブラリがいくつかあります。そのようなライブラリの 1 つがjTypesです。JavaScript プログラマーとしてのスキルに自信がある場合は、忘れずに補助輪を外してください。
注:個人的には、jTypes は少し好きではありません。
JavaScript におけるプロトタイプの継承
このセクションは、真のプロトタイプ継承について学ぶ準備ができたときに後で戻ってきて、次に何をすべきかを理解できるようにするためのマイルストーンとして書いています。
まず、次の行が間違っています。
JavaScript のプロトタイプ ベースのオブジェクト指向プログラミング スタイルは興味深いものですが、クラスからオブジェクトを作成する機能が必要になる状況は数多くあります。
これは次の理由で間違っています。
- JavaScript でクラスからオブジェクトを作成する必要はありません。
- JavaScript でクラスを作成する方法はありません。
はい、JavaScript で従来の継承をシミュレートすることは可能です。ただし、クラスではなくオブジェクトからプロパティを継承しています。たとえば、ECMAScript Harmony クラスは、プロトタイプ継承の古典的なパターンの構文糖衣にすぎません。
同じコンテキストで、あなたが示した例も間違っています:
たとえば、ベクトル描画アプリケーションでは、通常、描画の開始時にワークスペースは空です。既存の線から新しい「線」を作成できません。より一般的には、オブジェクトが動的に作成されるすべての状況で、クラスを使用する必要があります。
はい、最初はワークスペースが空であっても、既存の行から新しい行を作成できます。理解する必要があるのは、実際には線が描かれていないということです。
var line = {
x1: 0,
y1: 0,
x2: 0,
y2: 0,
draw: function () {
// drawing logic
},
create: function (x1, y1, x2, y2) {
var line = Object.create(this);
line.x1 = x1;
line.y1 = y1;
line.x2 = x2;
line.y2 = y2;
return line;
}
};
これで、上記の行を呼び出すだけで描画line.draw
できます。そうでなければ、そこから新しい行を作成できます。
var line2 = line.create(0, 0, 0, 100);
var line3 = line.create(0, 100, 100, 100);
var line4 = line.create(100, 100, 100, 0);
var line5 = line.create(100, 0, 0, 0);
line2.draw();
line3.draw();
line4.draw();
line5.draw();
線line2
、line3
、line4
およびは、描画すると正方形をline5
形成します。100x100
結論
これで、JavaScript のクラスは本当に必要ないことがわかります。オブジェクトで十分です。カプセル化は、関数を使用して簡単に実現できます。
そうは言っても、各インスタンスのパブリック関数がオブジェクトのプライベート状態にアクセスすることはできません。各インスタンスには独自のパブリック関数のセットが必要です。
ただし、これは問題ではありません。理由は次のとおりです。
- プライベートステートは本当に必要ありません。あなたはそう思うかもしれませんが、実際にはそうではありません。
- 変数を本当にプライベートにしたい場合は、ThiefMasterが述べたように、変数名の前にアンダースコアを付けて、ユーザーにそれをいじらないように伝えてください。