プロトタイプチェーンの継承
function c() {
this.b = !false;
}
c.prototype.a = function () {
return this.b;
};
function obj() {
this.bar = false;
}
obj.prototype = new c();
obj.prototype.foo = function () {
return this.bar;
};
var B = new obj();
console.log(B.a());デメリット:複数のインスタンスによる参照型の変更は、すべてのインスタンスオブジェクトに影響します;
function SuperType(){
this.colors = ["red", "blue", "green"];
}
function SubType(){}
SubType.prototype = new SuperType();
var instance = new SubType();
instance .colors.push("black");
alert(instance .colors); //"red,blue,green,black"
var instance2 = new SubType();
alert(instance2.colors); //"red,blue,green,black"コンストラクタの継承
function SuperType(){
this.color=["red","green","blue"];
}
function SubType(){
//SuperTypeから継承
SuperType.call(this);
}
var instance = new SubType();
instance .color.push("black");
alert(instance .color);//"red,green,blue,black"
var instance2 = new SubType();
alert(instance2.color);//"red,green,blue"長所:プロトタイプ連鎖継承における参照型の落とし穴を回避;
欠点:
- 親クラスから継承できるのはインスタンスの属性とメソッドだけで、プロトタイプの属性とメソッドは継承できません;
- 再利用は不可能で、各サブクラスは親クラスのインスタンス関数のコピーを持ち、パフォーマンスに影響します;
組合せ継承
コンストラクタ継承とプロトタイプ連鎖継承の組み合わせ
function SuperType(name){
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
alert(this.name);
};
function SubType(name, age){
// 継承された属性
// SuperType()の2回目の呼び出し
SuperType.call(this, name);
this.age = age;
}
// 継承メソッド
// プロトタイプ・チェーンの構築
// SuperType()の最初の呼び出し
SubType.prototype = new SuperType();
// サブタイプを書き換える.prototype属性で、自身のコンストラクタ SubType を指す。
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
alert(this.age);
};
var instance = new SubType("Nicholas", 29);
instance .colors.push("black");
alert(instance .colors); //"red,blue,green,black"
instance .sayName(); //"Nicholas";
instance .sayAge(); //29
var instance2 = new SubType("Greg", 27);
alert(instance2.colors); //"red,blue,green"
instance2.sayName(); //"Greg";
instance2.sayAge(); //27利点:コンストラクターとプロトタイプチェーンの利点を兼ね備えています;
寄生継承
function inheritPrototype(subType, superType){
var prototype = Object.create(superType.prototype); // 親クラスのプロトタイプのコピーを作成するオブジェクトを作成する。
prototype.constructor = subType; // プロトタイプのオーバーライドによってデフォルトのコンストラクタ属性が失われるのを補うために、オブジェクトを拡張する。
subType.prototype = prototype; // 新しく作成されたオブジェクトをサブクラスのプロトタイプに割り当てるオブジェクトを指定する。
}
// 親クラスはインスタンスとプロトタイプのプロパティを初期化する。
関数 SuperType{
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
alert(this.name);
};
// コンストラクタ渡しによるサブクラスのインスタンス・プロパティの拡張
関数 SubType{
SuperType.call(this, name);
this.age = age;
}
// 親クラスのプロトタイプを子クラスに指し示す
プロトタイプを継承する;
// 新しいサブクラスのプロトタイプ属性
SubType.prototype.sayAge = function(){
alert(this.age);
}
var instance = new SubType("xyc", 23);
var instance2 = new SubType("lxy", 23);
instance .colors.push("2"); // ["red", "blue", "green", "2"]
instance .colors.push("3"); // ["red", "blue", "green", "2","3"]長所:
- SuperTypeコンストラクタを1回呼び出すだけなので、SubType.prototypeに不要で冗長なプロパティを作成する必要がなく、効率的です。同時に、プロトタイプの連鎖はそのまま残るため、instanceof や isPrototypeOf() は普通に使用できます;





