Javascriptがプロトタイプベースの言語であることはどういう意味ですか?


255

Javascriptの主な利点の1つは、プロトタイプベースの言語であることです。

しかし、Javascriptがプロトタイプベースであるとはどういう意味ですか。なぜそれが利点なのでしょうか。


3
:この答えは、あなたが原型継承について知っておく必要があるすべてを説明しstackoverflow.com/a/16872315/783743
Aadit Mシャー

回答:


291

プロトタイプの継承は、オブジェクト指向コードの再利用の一形態です。Javascriptは、プロトタイプ継承を使用する唯一の[主流]オブジェクト指向言語の1つです。他のほとんどすべてのオブジェクト指向言語は古典的です。

では、古典の継承、プログラマはオブジェクトを定義するクラスを、書き込みます。同じクラスから複数のオブジェクトをインスタンス化できるため、プログラム内の複数のオブジェクトを記述するコードが1か所にあります。その後、クラスを階層に編成して、コードの再利用を促進できます。より一般的なコードは、下位のクラスが継承する上位のクラスに格納されます。これは、オブジェクトが同じクラスの他のオブジェクトとその親クラスとコードを共有していることを意味します。

原型継承フォーム、オブジェクトを直接継承する他のオブジェクトから。クラスに関するビジネスはすべてなくなります。オブジェクトが必要な場合は、オブジェクトを書き込むだけです。ただし、コードの再利用は依然として価値のあるものであるため、オブジェクトを階層でリンクすることができます。JavaScriptでは、すべてのオブジェクトに、それを作成したオブジェクトへの秘密のリンクがあり、チェーンを形成しています。オブジェクトが持っていないプロパティを要求されると、その親オブジェクトが要求されます...プロパティが見つかるまで、またはルートオブジェクトに到達するまで、チェーンを上に向かっていきます。

JavaScriptの各関数(オブジェクト自体)には、実際には「プロトタイプ」と呼ばれるメンバーがあり、オブジェクトが要求されたときに値を提供します。このメンバーがあると、コンストラクターメカニズム(関数からオブジェクトが構築されるメカニズム)が機能します。プロパティを関数オブジェクトのプロトタイプに追加すると、構築されたオブジェクトだけでなく、それを継承するすべてのオブジェクトでも使用できるようになります。

メリット

プロトタイプの継承がコード再利用の有利な形である理由について、厳密な規則はないかもしれません。コードの再利用自体は有利であり、プロトタイプの継承はそれを回避する賢明な方法です。プロトタイプ継承はコード再利用のかなり単純なモデルであり、そのコードは直接的な方法で頻繁に再利用できると主張するかもしれません。しかし、古典的な言語も確かにこれを達成することができます。

補足@Andrew Hedgesは、実際には多くのプロトタイプ言語があることを指摘します。これらの他のものが存在することは注目に値しますが、それらのどれも主流に近いものは何もないことも注目に値します。NewtonScriptはしばらくの間牽引力があるように見えましたが、そのプラットフォームで死にました。プロトタイプ機能を追加する方法で、いくつかの現代言語を拡張することも可能です。


9
やあケリー。JavaScriptはあるものの、これまでで最も人気の原型言語、他の多くのがあります。en.wikipedia.org/wiki/Prototype-based_programming#Languages
アンドリュー・ヘッジス

2
ねえアンドリュー。いい視点ね。もっとはっきりしていたはずです。書き留めておきます。
keparo

3
また、これをお読みくださいdeveloper.mozilla.org/en/JavaScript/Guide/...を
pramodc84

1
素晴らしい答えを得るには+1。マイナーなコメント:私にとって、古典的な継承はプロトタイプよりも「直接的な」ように見えます。実際、私はプロトタイプオブジェクトを(他のオブジェクトへの)単なるリンケージと見なしていますが、コンパイルされたOOPでは、基本クラスは「直接継承」されていると考えています。そのため、プロトタイプオブジェクトは継承されるのではなく、連鎖されます(継承はやや偽造されます)。何かご意見は?
囚人ZERO

3
@PrisonerZERO:プロトタイプの継承はクラシックよりも直接的であると私は主張します。オブジェクトBは、オブジェクトAが指すクラスから継承するクラスを指すのではなく、オブジェクトAを直接指し、「...を除いて、そのオブジェクトと同じです」と言います。プロトタイプの継承についての大きなこと、および多くの人にとって内部化するのが最も難しいと思われることは、インスタンスとタイプを区別しないことです。すべてのオブジェクトは、タイプとインスタンスの両方です。2つの間の区別は人工的で意図的なものであり、通常、クラス指向の考え方に行き詰まっている症状です。
cHao 2014

54

プロトタイプベースの言語は、クラスとオブジェクトを区別しません。単にオブジェクトがあるだけです。プロトタイプベースの言語には、プロトタイプオブジェクトという概念があります。これは、新しいオブジェクトの初期プロパティを取得するためのテンプレートとして使用されるオブジェクトです。オブジェクトは、作成時または実行時に、独自のプロパティを指定できます。さらに、任意のオブジェクトを別のオブジェクトのプロトタイプとして関連付けることができるため、2番目のオブジェクトが最初のオブジェクトのプロパティを共有できます。


6
非常に良い説明ですが、「初期プロパティのテンプレート」に関するコメントは少し誤解を招きます。オブジェクトをインスタンス化した後でプロトタイプを変更しても、そのオブジェクトは引き続きそれらの関数を受け取ります。
nickf 08年

32

プロトタイプベースのプログラミングは、クラスが存在しないオブジェクト指向プログラミングのスタイルであり、動作の再利用(またはクラスベースの言語での継承)は、プロトタイプとして機能する既存のオブジェクトを複製することによって実行されます。


あなたはまだこのように感じていますか?もしそうなら、これは私と一緒に本当にしっかりと「クリック」する最初の説明です。
Chazt3n 2016年

11

利点/欠点は、クラス(静的コード)を定義する必要なく、実行時に新しい種類のオブジェクトを作成できることです。ほとんどの機能と同様に、それを利点/欠点に変えるのは開発者次第です。

オブジェクトは基本的にJavaスクリプトの関数であるため、上記は可能です(クロージャも)。


動的オブジェクトはJavaScriptの利点ですが、JavaScriptがプロトタイプ言語または関数型言語であることには実際には関係ありません。多くの古典的な言語では、実行時に動的オブジェクトを作成できます。クロージャも多少無関係です。
keparo 2008年

2
クラスは必ずしも静的コードである必要はありません。クラス自体がオブジェクトであり、オブジェクトでもあるメタクラスから構成されているPythonを見てください。
TomaszZieliński、2011年

6

クラス構造を宣言する代わりに、同じタイプのオブジェクトを作成し、オブジェクトのプロトタイプを使用したいときにいつでもその定義に追加できます。それは物事を行う通常の方法よりも柔軟性があります。


6

コンパイル時にクラスではなく実行時にオブジェクトを使用して新しいオブジェクトを構築する場合、これにより、オブジェクトの詳細を知らなくてもオブジェクトを拡張できる可能性が広がります。もちろん、使い方次第では短期間でデメリットになるかもしれません。ここでは言語については想定していません。そのため、JavaScript以外の動的でない言語にも適用できます。

myobject.prototype=unkownobject;
myobject.newproperty=1;

どこからでもオブジェクトを取得できます。ネットワーク、データベース、外部リンケージなどからの独自のコード。

言語はjavascriptのようなプロトタイプ継承を実装する必要がないことに注意してください。javascriptでは、プロトタイプオブジェクトは単に共有されるだけでなく、そのプロパティも継承者間で共有されます。代わりに、プロトタイプのすべてのプロパティを新しいオブジェクトにコピーします。それぞれのアプローチには、さまざまな状況で長所があります。私は2番目がもっと好きですが、それはjavascriptがすることではありません。


6

すべての答えを読んだ後、これは結論です

1)オブジェクトが他のオブジェクトから直接継承される継承

2)クラスを使用しない

3)インスタンスベースのプログラミングまたはクラスレスプロトタイプ指向プログラミングとも呼ばれます

4)動作の再利用は、プロトタイプとして機能する既存のオブジェクトを複製することによって実行されます

5)新しいオブジェクトからテンプレートとして使用されるオブジェクトは、初期プロパティを取得します

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.