目次
1.プロトタイプの概念を確認します。
プロトタイプチェーンの継承を学ぶ前に、プロトタイプの概念を簡単に確認しましょう。
各関数には、デフォルトで空のObjectオブジェクト(プロトタイプオブジェクトと呼ばれる)を指すプロトタイプ属性があり、プロトタイプオブジェクトには、関数オブジェクトを指すコンストラクター属性があります。
function foo(){
}
console.log(foo.prototype.constructor == foo); //true
コンストラクター、プロトタイプ、およびインスタンス間の関係:
各コンストラクターにはプロトタイプオブジェクト(Foo.prototype)があり、プロトタイプオブジェクトにはコンストラクター(コンストラクター)へのポインターが含まれ、インスタンスにはプロトタイプオブジェクトへの内部ポインター(_proto_)が含まれます。
function Foo(){
this.name="小白";
}
var foo = new Foo();
console.log(foo.name);
console.log(Foo.prototype.constructor === Foo);
console.log(foo.__proto__ === Foo.prototype);
第二に、プロトタイプチェーンの継承
// 创建SuperType函数 并添加property属性
function SuperType() {
this.property = true;
}
// 给其原型上添加一个方法 getSuperValue
SuperType.prototype.getSuperValue = function () {
return this.property;
};
// 创建一个SubType函数 并添加subproperty属性
function SubType(){
this.subproperty = false;
}
// 继承SuperType(重点)
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function () {
return this.subproperty;
};
var instance = new SubType();
alert(instance.getSuperValue());
説明:上記のコードは、SuperTypeとSubTypeの2つのタイプを定義しています。各タイプには、属性とメソッドがあります。それらの主な違いは、SubTypeがSuperTypeを継承し、継承はSuperTypeのインスタンスを作成し、そのインスタンスをSubType.prototypeに割り当てることによって実現されることです。実現の本質は、プロトタイプオブジェクトを書き直し、SubTypeのプロトタイプオブジェクトをSuperTypeのインスタンスとして使用することです。次に、SuperTypeインスタンスに元々存在していたすべてのプロパティとメソッドが、SubType.prototypeにも存在するようになりました。継承関係を確立した後、SubType.prototypeにメソッドを追加し、SuperTypeのプロパティとメソッドの継承に基づいて新しいメソッドを追加しました。
上記のコードでは、デフォルトでSubTypeによって提供されるプロトタイプを使用しませんでしたが、新しいプロトタイプに置き換えました。このプロトタイプはSuperTypeのインスタンスです。したがって、新しいプロトタイプには、SuperTypeのインスタンスが所有するすべてのプロパティとメソッドがあるだけでなく、SuperTypeのプロトタイプを指すポインターも含まれています。
console.log(SubType.prototype.__proto__ === SuperType.prototype); //true
最終結果は、インスタンスがSubTypeのプロトタイプを指し、SubTypeのプロトタイプがSuperTypeのプロトタイプを指すということです。
3.注意点:
1.デフォルトのプロトタイプを忘れないでください。
すべての関数の明示的なプロトタイプは、Objectを除く空のObjectオブジェクトを指しているため、デフォルトのプロトタイプにはObject.prototypeへの内部ポインターが含まれます。これが、すべてのカスタムタイプがtoString()やvalueOf()などのデフォルトメソッドを継承する根本的な理由です。
2.慎重な定義方法:
サブタイプがスーパータイプのメソッドを更新する必要がある場合や、スーパータイプに存在しないメソッドを追加する必要がある場合があります。プロトタイプにメソッドを追加するコードは、プロトタイプを置き換えるステートメントの後に配置する必要があります。
function SuperType() {
this.property = true;
}
SuperType.prototype.getSuperValue = function () {
return this.property;
};
function SubType(){
this.subproperty = false;
}
// 继承SuperType
SubType.prototype = new SuperType();
//添加新方法
SubType.prototype.getSubValue = function () {
return this.subproperty;
};
//重新超类中的方法
SubType.prototype.getSuperValue = function () {
return false;
};
var instance = new SubType();
alert(instance.getSuperValue());
3.プロトタイプチェーンを介して継承を実装する場合、オブジェクトリテラルを使用してプロトタイプメソッドを作成することはできません。プロトタイプチェーンを書き換えるから
function SuperType() {
this.property = true;
}
SuperType.prototype.getSuperValue = function () {
return this.property;
};
function SubType(){
this.subproperty = false;
}
// 继承SuperType
SubType.prototype = new SuperType();
//使用对象字面量添加新方法
SubType.prototype = {
getSubValue : function(){
return this.subproperty;
},
someOtherMethod : function(){
return false;
}
};
var instance = new SubType();
alert(instance.getSuperValue());
4:プロトタイプチェーンの問題:
1.参照型の値を含むプロトタイププロパティはすべてのインスタンスで共有されます。そのため、プロパティはプロトタイプオブジェクトではなくコンストラクターで定義されます。
function SuperType(){
this.colors = ["red","blue","green"];
}
function SubType() {
}
// 继承了SuperType
SubType.prototype = new SuperType();
var instance = new SubType();
instance.colors.push("black");
alert(instance.colors);
var instance2 = new SubType();
alert(instance2.colors);
この例では、SuperTypeコンストラクターは、配列(参照データ型)を含むcolorsプロパティを定義します。SuperTypeの各インスタンスにはcolors属性があります。SubTypeがプロトタイプチェーンを介してSuperTypeを継承する場合、colorsプロパティもあります。重要なのは、SubTypeがこのプロパティを共有するため、インスタンスインスタンスで配列colorsの値が変更された後、instance2のcolors値も変更されていることがわかります。
2.サブタイプのインスタンスを作成する場合、スーパータイプのコンストラクターにパラメーターを渡すことはできません。
注:詳細については、「JavaScriptAdvancedProgramming」を参照してください。