JavaScript六種類の非常に古典的な対象継承方式
6866 ワード
一、プロトタイプチェーン継承
ポイント:原型を利用して、一つの引用タイプにもう一つの引用タイプの属性と方法を継承させます.構造関数、プロトタイプ、インスタンス間の関係:各構造関数にはプロトタイプオブジェクトがあり、プロトタイプオブジェクトにはコンストラクタへのポインタが含まれていますが、例にはプロトタイプオブジェクトへの内部ポインタが含まれています.
短所:①プロトタイプチェーンは複数の例の引用タイプの属性を継承して同じ方向に指しています.例によってプロトタイプの属性が修正され、他の例のプロトタイプの属性も修正されます.②パラメータを渡すことができません.③単一継承
二、構造関数を借りて継承する
重点:call()と.appy()を使用して、親の構造関数をサブクラス関数に導入し、親の構造関数を使用して、強子クラスのインスタンスを増加させ、親クラスのインスタンスを子クラスにコピーするのと同じです.
短所:①親類の実例的な属性と方法だけを継承して、原型の属性/方法を継承できません.②コンストラクタの多重化ができず、各サブクラスには親の実例関数のコピーがあり、性能に影響を与え、コードが大きく膨れてしまう.
三、コンビネーション引継ぎ
ポイント:プロトタイプチェーンの継承と構造関数の継承の2つのモードの利点を組み合わせて、親の構造を呼び出すことによって、父のクラスの属性を継承し、参照を保持し、親のインスタンスをサブプロトタイプとして、関数多重化を実現します.
プロトタイプチェーンを使用してプロトタイプの属性と方法の継承を実現し、構造関数を借りることによって実例的な属性の継承を実現するという考え方の背後には、プロトタイプ上の定義方法によって関数多重を実現しただけでなく、各インスタンスにその独自の属性があることを保証することができる.
四、原型式継承
ポイント:オブジェクトを一つの関数で包んで、この関数の呼び出しを返します.この関数は属性を任意に加えることができるインスタンスまたはオブジェクトになります.object.create()はこの原理で、あるオブジェクトを直接構造関数のプロトタイプに値します.
五、寄生式継承
重点:オブジェクトを強化するために内部にある方法で、最後にコンストラクタに戻るパッケージ継承プロセスの関数だけを作成します.(原型式の外に殻をかぶせて、リターンするように)
六、寄生組合式継承
重点:構造関数伝達パラメータと寄生モードを借りることによって継承属性を実現し、プロトタイプチェーンの混成形式によって方法を継承し、関数にappyまたはcallを用いて別の構成関数を導入することで、参照できる.
短所:実現の過程は比較的煩雑である.
なぜこれらの継承方式を学ぶべきですか?直接継承できるのになぜこんなに面倒くさいですか?主に彼らの思想を学ぶために、より良い基础を筑いて、后でフレームのソースコードを読むために、あるいは自分でコンポーネントをカプセル化します.
時間がちょっと忙しいです.ES 6のextensを入れていません.時間があったらまた補充します.
ポイント:原型を利用して、一つの引用タイプにもう一つの引用タイプの属性と方法を継承させます.構造関数、プロトタイプ、インスタンス間の関係:各構造関数にはプロトタイプオブジェクトがあり、プロトタイプオブジェクトにはコンストラクタへのポインタが含まれていますが、例にはプロトタイプオブジェクトへの内部ポインタが含まれています.
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;
};
var example = new SubType();
alert(example.getSuperValue());//true
原型を使ってオブジェクトを作成すると、複数のインスタンスが引用タイプの操作によって改竄されるという問題があります.function SuperType(){
this.colors = ["red", "blue", "green"];
}
function SubType(){}// ,
SubType.prototype = new SuperType();
var example1 = new SubType();
example1.colors.push("black");
alert(example1.colors); //"red,blue,green,black"
var example2 = new SubType();
alert(example.colors); //"red,blue,green,black"
2つのインスタンスオブジェクトのexample 1とexample 2のColors属性は同じ方向を指し、他のインスタンスの属性に影響を与えるように変更される.短所:①プロトタイプチェーンは複数の例の引用タイプの属性を継承して同じ方向に指しています.例によってプロトタイプの属性が修正され、他の例のプロトタイプの属性も修正されます.②パラメータを渡すことができません.③単一継承
二、構造関数を借りて継承する
重点:call()と.appy()を使用して、親の構造関数をサブクラス関数に導入し、親の構造関数を使用して、強子クラスのインスタンスを増加させ、親クラスのインスタンスを子クラスにコピーするのと同じです.
function SuperType(name){
this.name = name;
this.colors = ["red", "blue", "green"];
}
function SubType(name, age){
// SuperType
SuperType.call(this, name);
this.age = age;
}
var example1 = new SubType("Mike", 23);
example1.colors.push("black");
alert(example1.colors);//"red,blue,green,black"
var example2 = new SubType();
alert(example2.colors);//"red,blue,green"
alert(example1.name); // "Mike"
alert(example1.age); // 23
構造関数の継承のポイントはSuperType.callで、SuperType構造関数を呼び出して、SubTypeの各インスタンスはSuperTypeの属性をコピーします.短所:①親類の実例的な属性と方法だけを継承して、原型の属性/方法を継承できません.②コンストラクタの多重化ができず、各サブクラスには親の実例関数のコピーがあり、性能に影響を与え、コードが大きく膨れてしまう.
三、コンビネーション引継ぎ
ポイント:プロトタイプチェーンの継承と構造関数の継承の2つのモードの利点を組み合わせて、親の構造を呼び出すことによって、父のクラスの属性を継承し、参照を保持し、親のインスタンスをサブプロトタイプとして、関数多重化を実現します.
プロトタイプチェーンを使用してプロトタイプの属性と方法の継承を実現し、構造関数を借りることによって実例的な属性の継承を実現するという考え方の背後には、プロトタイプ上の定義方法によって関数多重を実現しただけでなく、各インスタンスにその独自の属性があることを保証することができる.
function SuperType(name){
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
alert(this.name);
};
function SubType(name, age){
//
SuperType.call(this, name);
this.age = age;
}
//
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
alert(this.age);
};
var example1 = new SubType("Mike", 23);
example1.colors.push("black");
alert(example1.colors); //"red,blue,green,black"
example1.sayName(); //"Mike";
example1.sayAge(); //23
var example2 = new SubType("Jack", 22);
alert(example2.colors); //"red,blue,green"
example2.sayName(); //"Jack";
example2.sayAge(); //22
欠陥:親類における例示的な属性と方法は、サブクラスの例としても、サブクラスのプロトタイプとしても存在するが、メモリ占有のみであるため、サブクラスを使用してインスタンスオブジェクトを作成する場合、そのプロトタイプには同じ属性/方法が2つ存在する.この方法はjavascriptで最も一般的な継承モードです.四、原型式継承
ポイント:オブジェクトを一つの関数で包んで、この関数の呼び出しを返します.この関数は属性を任意に加えることができるインスタンスまたはオブジェクトになります.object.create()はこの原理で、あるオブジェクトを直接構造関数のプロトタイプに値します.
function object(obj){
function O(){}
O.prototype = obj;
return new O();
}
object()はその中に入ってきたオブジェクトに対して浅い複製を行い、Oの原型を直接に伝わったオブジェクトに向けます.var person = {
name: "Mike",
friends: ["Jack", "Tom", "Joes"]
};
var anotherPerson = object(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Peter");
var yetAnotherPerson = object(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("BoBo");
alert(person.friends); //"Jack,Tom,Joes,Peter,BoBo"
ECMAScript 5は、Object.creat()を追加することにより、プロトタイプ継承を規範化し、この方法では、新しいオブジェクトのプロトタイプとして使用するオブジェクトと、新しいオブジェクトとして追加の属性を定義するオブジェクトとを受信する.var person = {
name:"EvanChen",
friends:["Shelby","Court","Van"];
};
var anotherPerson = Object.create(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");
var yetAnotherPerson = Object.create(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");
console.log(person.friends);//"Shelby","Court","Van","Rob","Barbie"
短所:①プロトタイプチェーンは複数の例の引用タイプの属性を継承して同じ方向を指しています.(すべての例はプロトタイプの属性を継承します.)改竄の可能性があります.②パラメータを渡すことができず、多重化ができませんでした.(新しいインスタンスのプロパティは全部後に追加されます).五、寄生式継承
重点:オブジェクトを強化するために内部にある方法で、最後にコンストラクタに戻るパッケージ継承プロセスの関数だけを作成します.(原型式の外に殻をかぶせて、リターンするように)
function createAnother(original){
varclone=object(original); //
clone.sayHi = function(){ //
alert("hi");
};
return clone; //
}
関数の主な役割は,関数を増強するための構造関数の属性と方法を追加することである.var person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi(); //"hi"
短所:①プロトタイプチェーンは複数の例の引用タイプの属性を継承して同じ方向を指しています.改竄の可能性があります.②パラメータを渡すことができず、プロトタイプを使わず、多重化できませんでした.六、寄生組合式継承
重点:構造関数伝達パラメータと寄生モードを借りることによって継承属性を実現し、プロトタイプチェーンの混成形式によって方法を継承し、関数にappyまたはcallを用いて別の構成関数を導入することで、参照できる.
function inheritPrototype(subType, superType){
var prototype = Object.create(superType.prototype); //Object.create
prototype.constructor = subType; //
subType.prototype = prototype; //
}
//
function SuperType(name){
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
alert(this.name);
};
// ( )
function SubType(name, age){
SuperType.call(this, name);
this.age = age;
}
//
inheritPrototype(SubType, SuperType);
//
SubType.prototype.sayAge = function(){
alert(this.age);
}
var example1 = new SubType("abc", 21);
var example2 = new SubType("def", 22);
example1.colors.push("pink"); // ["red", "blue", "green", "pink"]
example1.colors.push("black"); // ["red", "blue", "green", "black"]
寄生グループは、前の幾つかの継承利点を集約し、上の継承方式のすべての欠陥をほぼ回避し、実行効率が最も高く、応用面が最も広い.短所:実現の過程は比較的煩雑である.
なぜこれらの継承方式を学ぶべきですか?直接継承できるのになぜこんなに面倒くさいですか?主に彼らの思想を学ぶために、より良い基础を筑いて、后でフレームのソースコードを読むために、あるいは自分でコンポーネントをカプセル化します.
時間がちょっと忙しいです.ES 6のextensを入れていません.時間があったらまた補充します.