JavaScriptのOO思想(二)
11876 ワード
対象に向かう言語には四つの基本的な特性があると知っています.抽象性とは、一致したデータ構造(属性)と動作(操作)を有するオブジェクトを抽象的にクラス化することをいう.一つのクラスはこのような抽象的なもので、応用に関する重要な性質を反映しています.他のいくつかの無関係な内容を無視しています.どのクラスの区分も主観的であるが、具体的な応用に関連していなければならない.C〓〓などの対象言語には抽象的な概念があり、抽象的な類を引き継いで抽象的な類の中の方法を実現しなければならないが、JSには類の概念が存在しないため、書き直しなどのキーワードが存在しないため、JSには抽象的な概念がない.JSは弱いタイプの言語で、どのタイプもいずれの属性にも値が付けられますので、JSは多状態をサポートしていると言えます.したがって、全体的にJSは継承、パッケージ、多状態をサポートしています.前に述べた対象の創建については、パッケージとして理解できますが、今回は主にこの継承の考えを述べます.
他の対象言語と違って、JSでの継承も独自の実現方式を持っています.基本的には以下の6つの中に実装されています.プロトタイプチェーン、プロトタイプ継承、寄生式継承、寄生結合式継承.
1、プロトタイプチェーンとは、プロトタイプチェーンの継承とは、親オブジェクトを直接にサブオブジェクトに割り当てるプロトタイプのことで、このようなオブジェクトはプロトタイプを通じて親オブジェクトの属性と方法にアクセスすることができます.新しいオブジェクトを作成する時、プロトタイプのポインタはデフォルトでObjectオブジェクトに向けられますので、プロトタイプのポインタを通してobjectにアクセスする方法があります.例えば、tostringメソッドでは、オブジェクトは実際にプロトタイプチェーンを通してObjectオブジェクトを継承しています.プロトタイプチェーンの継承方式は以下の通りです.
1、C(登録商標)、Java(Java)などのオブジェクト指向言語とは異なり、クラスを継承する手段ではなく、1つの親オブジェクトのインスタンスをサブオブジェクトのプロトタイプポインタに値して継承する2、この方式を使用した継承は、インスタンス中の方法だけでなく、その属性を継承するものであり、その属性は静的、すなわちサブオブジェクトの例で変化するものと言える.他の例でも変更されます.3、デフォルトのプロトタイプのオブジェクトには関数自体を指すconstructor属性があると知っていますが、現在はプロトタイプのオブジェクト全体が書き換えられています.サブオブジェクトの構造関数は、現在のsubのconstructorがSuperType関数を指しています.
2、構造関数を借りて原型チェーンを使って継承を実現できますが、このような継承は完璧ではありません.ほとんどの場合、継承したい属性は原型の対象の中にあります.このようにもたらす負の効果は全身を引っ張って、どこでも変えられます.このような実現はいくつかの特定の需要を満たすことができません.したがって、私たちは、子オブジェクトが親オブジェクトの属性を継承し、各サブオブジェクトの属性が独立していることを望むなら、他の実装を考慮しなければならない.ここでは、別の実施方法を示します.構造関数を借ります.この方法は属性継承の問題を解決することができる.
1、この実装は、プロトタイプオブジェクト2、プロトタイプの中のconstructorが指すのか、それともサブオブジェクト関数タイプそのものか3、親タイプのプロトタイプのオブジェクト対サブタイプが見えない.
だから、私たちは子供のタイプが父のタイプの原型を受け継ぐことができると思う時、構造関数の方式を借りるのは需要を満たすことができないのです.
3、組み合わせは名前の通りに継承されます.プロトタイプチェーン+借用構造関数が継承されています.経典の疑似継承とも言われます.プロトタイプチェーンを使用して父のタイプのプロトタイプの属性と方法を継承し、構造関数を借用して実例的な属性と方法の継承を実現するという考えです.多く話しません.コードを見てください.
4、原型式継承
構造関数を作成したくなくて、一つのオブジェクトと他のオブジェクトを同じようにしたいなら、原型式で継承できます.
6、寄生結合式継承前に述べた組み合わせ継承はJavaScriptの中で最も一般的なモードであり、組み合わせ継承の不足は2回の構造関数を呼び出し、結果として冗長性の属性または方法を生み出している.
他の対象言語と違って、JSでの継承も独自の実現方式を持っています.基本的には以下の6つの中に実装されています.プロトタイプチェーン、プロトタイプ継承、寄生式継承、寄生結合式継承.
1、プロトタイプチェーンとは、プロトタイプチェーンの継承とは、親オブジェクトを直接にサブオブジェクトに割り当てるプロトタイプのことで、このようなオブジェクトはプロトタイプを通じて親オブジェクトの属性と方法にアクセスすることができます.新しいオブジェクトを作成する時、プロトタイプのポインタはデフォルトでObjectオブジェクトに向けられますので、プロトタイプのポインタを通してobjectにアクセスする方法があります.例えば、tostringメソッドでは、オブジェクトは実際にプロトタイプチェーンを通してObjectオブジェクトを継承しています.プロトタイプチェーンの継承方式は以下の通りです.
function SuperType(){
this.name = "I'm super type";
}
SuperType.prototype.sayHi = function(first_argument) {
alert("Hi");
};
function SubType(){
}
SubType.prototype = new SuperType();
var sub = new SubType();
sub.sayHi();//Hi
alert(sub.name);//I'm super type
alert(sub.constructor == SuperType);//true
上記のプロトタイプチェーンによって継承された例は以下の点に難くないです.1、C(登録商標)、Java(Java)などのオブジェクト指向言語とは異なり、クラスを継承する手段ではなく、1つの親オブジェクトのインスタンスをサブオブジェクトのプロトタイプポインタに値して継承する2、この方式を使用した継承は、インスタンス中の方法だけでなく、その属性を継承するものであり、その属性は静的、すなわちサブオブジェクトの例で変化するものと言える.他の例でも変更されます.3、デフォルトのプロトタイプのオブジェクトには関数自体を指すconstructor属性があると知っていますが、現在はプロトタイプのオブジェクト全体が書き換えられています.サブオブジェクトの構造関数は、現在のsubのconstructorがSuperType関数を指しています.
2、構造関数を借りて原型チェーンを使って継承を実現できますが、このような継承は完璧ではありません.ほとんどの場合、継承したい属性は原型の対象の中にあります.このようにもたらす負の効果は全身を引っ張って、どこでも変えられます.このような実現はいくつかの特定の需要を満たすことができません.したがって、私たちは、子オブジェクトが親オブジェクトの属性を継承し、各サブオブジェクトの属性が独立していることを望むなら、他の実装を考慮しなければならない.ここでは、別の実施方法を示します.構造関数を借ります.この方法は属性継承の問題を解決することができる.
function SuperType(){
this.name = "Li Lei";
this.sayHi = function() {
alert("Hi");
};
}
SuperType.prototype.show = function() {
alert("Hello world");
};
function SubType(){
SuperType.call(this);
}
var sub = new SubType();
sub.sayHi();//Hi
alert(sub.name);//Li Lei
alert(sub.constructor == SubType);//true
alert(sub.show);//undefined
このような継承を実現する方法は,親タイプの構造関数をサブタイプの構造関数の内部で呼び出すだけであることを見ることができる.このような方法を実現できる主な原因は、関数が特定の環境でコードを実行するオブジェクトであるため、appy()とcall()の方法を用いることによって、新たに作成されたオブジェクト上でコンストラクションを実行することもできるからである.今やっていることは、サブオブジェクトの現在のスコープを関数SuperTypeに与え、SuperType関数を実行します.このときSuperType関数の中のthisはsubであるため、subはnameとsayHi属性を持つようになります.このような実現方法には以下の点があります.1、この実装は、プロトタイプオブジェクト2、プロトタイプの中のconstructorが指すのか、それともサブオブジェクト関数タイプそのものか3、親タイプのプロトタイプのオブジェクト対サブタイプが見えない.
だから、私たちは子供のタイプが父のタイプの原型を受け継ぐことができると思う時、構造関数の方式を借りるのは需要を満たすことができないのです.
3、組み合わせは名前の通りに継承されます.プロトタイプチェーン+借用構造関数が継承されています.経典の疑似継承とも言われます.プロトタイプチェーンを使用して父のタイプのプロトタイプの属性と方法を継承し、構造関数を借用して実例的な属性と方法の継承を実現するという考えです.多く話しません.コードを見てください.
function SuperType(){
this.name = "Li Lei";
}
SuperType.prototype.show = function() {
alert("Hello world");
};
function SubType(){
SuperType.call(this);
}
SubType.prototype = new SuperType();
var sub = new SubType();
alert(sub.name);//Li Lei
alert(sub.constructor == SuperType);//false
sub.show();//Hello world
ここではSubTypeのプロトタイプにも属性nameがありますが、借用構造関数方式を利用して、構造関数内部でnameを定義しました.この時はプロトタイプのnameをカバーしました.このことから,結合はプロトタイプ鎖と借用構造関数を融合させた利点を継承し,それぞれの発生した欠陥を回避した.しかし、組み合わせ継承も完璧ではなく、2回の父親タイプの構造関数を呼び出して、冗長な方法と属性を生成することができます.例えば、上記の例では、プロトタイプオブジェクトとインスタンスオブジェクトはname属性を持っています.4、原型式継承
構造関数を作成したくなくて、一つのオブジェクトと他のオブジェクトを同じようにしたいなら、原型式で継承できます.
function create(obj){
function F(){};
F.prototype = obj;
return new F();
}
var people = {
name: "Li Lei",
friends: ["Han Meimei", "Jim Green"]
}
var tom = create(people);
tom.name = "Tom";
tom.friends.push("Li Lei");
var lucy = create(people);
lucy.name = "Lucy";
lucy.friends.push("Tom");
alert(people.friends);//Han Meimei,Jim Green,Li Lei,Tom
ECMAScript 5において、Object.create()を追加することにより、2つのパラメータを受け入れる.一つは新しいオブジェクトの原型として使用するオブジェクトであり、一つのオブジェクトだけが導入された場合、この方法は上記の例の方法createの表現と一致する.var people = {
name: "Li Lei",
friends: ["Han Meimei", "Jim Green"]
}
var tom = Object.create(people);
tom.name = "Tom";
tom.friends.push("Li Lei");
var lucy = Object.create(people);
lucy.name = "Lucy";
lucy.friends.push("Tom");
alert(people.friends);//Han Meimei,Jim Green,Li Lei,Tom
5、寄生式継承これはプロトタイプの継承と密接に関連した継承であり、寄生構造モードと工場モードと類似している.かなりそれで強化版の原型式が継承されました.function create(obj){
function F(){};
F.prototype = obj;
return new F();
}
function createParasitic(obj){
var para = create(obj);
para.sayHi = function(){
alert("Hi");
}
return para;
}
var people = {
name: "Li Lei",
friends: ["Han Meimei", "Jim Green"]
}
var lily = createParasitic(people);
lily.sayHi();// Hi
このようなやり方の結果は、他の相手と似たような相手を得ただけでなく、その相手に自分の欲しい方法を追加しました.6、寄生結合式継承前に述べた組み合わせ継承はJavaScriptの中で最も一般的なモードであり、組み合わせ継承の不足は2回の構造関数を呼び出し、結果として冗長性の属性または方法を生み出している.
function SuperType(){
this.name = "Li Lei";
}
SuperType.prototype.show = function() {
alert("Hello world");
};
function SubType(){
SuperType.call(this); //
}
SubType.prototype = new SuperType(); //
var sub = new SubType();
alert(sub.name);//"Li Lei"
alert(sub.constructor == SuperType);//true
sub.show();//Hello world
寄生結合式とは、構造関数を借用して属性を継承し、プロトタイプチェーンを混合して継承する方法をいう.そのテーマ思想は、子タイプのプロトタイプのために父タイプのコンストラクタを呼び出す必要がないということです.私たちが必要なのは、父タイプのプロトタイプのオブジェクトのコピーだけです.その実現方法は以下の通りである.function create(obj){
function F(){};
F.prototype = obj;
return new F();
}
function inheritPrototype(subType, superType){
var proto = create(superType.prototype);
proto.constructor = subType;
subType.prototype = proto;
}
寄生の組み合わせを使って引き継ぐ例を見てみましょう.function create(obj){
function F(){};
F.prototype = obj;
return new F();
}
function inheritPrototype(subType, superType){
var proto = create(superType.prototype);
proto.constructor = subType;
subType.prototype = proto;
}
function SuperType(){
this.name = "Li Lei";
}
SuperType.prototype.show = function() {
alert("Hello world");
};
function SubType(){
SuperType.call(this); //
}
inheritPrototype(SubType, SuperType);
var sub = new SubType();
alert(sub.name);//"Li Lei"
alert(sub.constructor == SubType);//true
sub.show();//Hello world
ここで、基本的な継承方式はすでに言いました.どの方式も長所と短所があります.