オブジェクト指向プログラミングを使う場合、当然ながらオブジェクト間の継承関係は欠かせません!プロトタイプは、JavaScript 継承を実装するための非常に重要な方法です。
まず次のコードを見てみましょう:
関数 person (名前, 年齢) {
this.name = 名前;
this.age = 年齢;
person.prototype.getInfo = function() {
alert( "私の名前は " this.name " で、年齢は " this.age " です。
}
var zhangchen = new person("zhangchen", 23); ); // 出力 私の名前は zhangchen で、年齢は 23 歳です。
実行結果から、キーワード new によって作成された zhangchen オブジェクトは、試作本人)方法です。新しく作成された zhangchen オブジェクトが person オブジェクトの属性とメソッドをどのように継承するかを詳しく見てみましょう。
プロトタイプ: JavaScript を使用したオブジェクト指向プログラミングでは、プロトタイプ オブジェクトが中心的な概念です。この名前は、JavaScript のオブジェクトが既存のインスタンス (つまり、プロトタイプ) オブジェクトのコピーとして作成されるという概念に由来しています。このプロトタイプ オブジェクトのプロパティとメソッドは、プロトタイプのコンストラクターから作成されたオブジェクトのプロパティとメソッドとして表示されます。これらのオブジェクトは、プロトタイプからプロパティとメソッドを継承していると言えます。 zhangchen オブジェクトを作成する場合:
var zhangchen =新しい会社( "zhangchen"、23);
zhangchen によって参照されるオブジェクトは、コンストラクター (この場合は関数 person) のプロパティに由来するプロトタイプからプロパティとメソッドを継承します。
JavaScript では、すべての関数にプロトタイプと呼ばれる属性があり、プロトタイプ オブジェクトを参照するために使用されます。このプロトタイプ オブジェクトにはコンストラクターと呼ばれるプロパティがあり、このプロパティは関数自体を参照します。これは循環参照です。次の図は、この循環関係をわかりやすく示しています。
図 1 循環関係
ここで、new 演算子を介して関数を持つオブジェクト (上記の例では person) を作成すると、取得されたオブジェクトは person.prototype のプロパティを継承します。上の画像では、person.prototype オブジェクトに person 関数を参照するコンストラクター プロパティがあることがわかります。このようにして、各 person オブジェクト (person.prototype から継承) は、person 関数を参照するコンストラクター プロパティを持ちます。
次のコードを使用して、このループが正しいかどうかを確認できます:
関数 person(名前, 年齢) {
this.name = 名前;
this.age = 年齢;
person.prototype.getInfo = function() {
alert("私の名前は " this.name "、そして私は " this.age " 歳です");
}
var zhangchen = 新しい人("zhangchen", 23);
alert(zhangchen.constructor == person.prototype.constructor); // true を出力します
alert(zhangchen.constructor == person); // true を出力します
alert(person.prototype. isPrototypeOf(zhangchen)) ; //output true
上記のコードの「isPrototypeOf()」メソッドの呼び出しはどこから来たのでしょうか? person.prototypeオブジェクトからのものでしょうか?いいえ、実際には、person.prototype および person インスタンスには、toString、toLocaleString、および valueOf と呼ばれる他のメソッドがありますが、それらはどれも person.prototype からのものではありません。むしろ、これは、すべてのプロトタイプの究極の基本プロトタイプである JavaScript の Object.prototype から来ています。 (Object.prototype のプロトタイプは null です。)
上記の例では、zhangchen.prototype がオブジェクトです。これは、オブジェクト コンストラクター (表示されませんが) を呼び出すことによって作成されます。これは、次のコードを実行するのと同じです:
コードをコピー
コードは次のとおりです。 zhangchen.prototype = new Object();
つまり、person インスタンスが person.prototype を継承するのと同じように、zhangchen.prototype は Object.prototype を継承します。これにより、すべての zhangchen インスタンスも Object.prototype のメソッドとプロパティを継承します。
プロトタイプ チェーン: すべての JavaScript オブジェクトはプロトタイプ チェーンを継承し、すべてのプロトタイプは Object.prototype で終了します。この継承はアクティブなオブジェクト間で行われることに注意してください。これは、宣言時に発生するクラス間の継承を指す、一般的な継承の概念とは異なります。したがって、JavaScript の継承はより動的になります。これは、次のような単純なアルゴリズムを使用して実現されます。オブジェクトのプロパティ/メソッドにアクセスしようとすると、JavaScript はそのオブジェクトにプロパティ/メソッドが定義されているかどうかを確認します。そうでない場合は、オブジェクトのプロトタイプがチェックされます。そうでない場合は、オブジェクトのプロトタイプのプロトタイプがチェックされ、Object.prototype に至るまで同様にチェックされます。次の図は、この解析プロセスを示しています:
図 2 toString() メソッドの解析プロセス
上記の解析プロセスにより、オブジェクトにプロパティ/メソッド X が定義されている場合、同じ名前のプロパティ/メソッドがオブジェクトのプロトタイプに隠蔽されます。たとえば、person.prototype で toString メソッドを定義することで、Object.prototype の toString メソッドをオーバーライドできます。
次のコードをもう一度見てください:
関数 person(名前 , 年齢) {
this.name = 名前
this.age = 年齢;
person.prototype.getInfo = function() {
alert( "私の名前は " this .name " で、年齢は " this.age " です。
}
var zhangchen = new person("zhangchen", 23); person("luomi", 23);
zhangchen.getInfo(); // 出力 私の名前は zhangchen です。
luomi.getInfo(); // 出力 私の名前は luomi です。私は23歳です ;
luomi.getInfo = function() {
alert("ここでgetInfoの関数を書き換えることができます!");
}
luomi.getInfo();ここで getInfo の関数を書き換えることができます!
zhangchen.getInfo(); // 出力 私の名前は zhangchen です。
実行結果からわかるように、 person の各インスタンスは person.prototype 内のメソッドを継承しますが、インスタンス化されたオブジェクト内のプロトタイプ オブジェクト内のメソッドを再定義することもでき、他のインスタンスには影響しません。
以上はプロトタイプとプロトタイプチェーンの継承方法についての私の理解です(
JavaScript: オブジェクト指向技術を使用して高度な Web アプリケーションを作成する
)を参照してください。 !