ホームページ >ウェブフロントエンド >jsチュートリアル >JS Pro - オブジェクト指向プログラミングにおける継承を詳しく解説_JavaScriptスキル

JS Pro - オブジェクト指向プログラミングにおける継承を詳しく解説_JavaScriptスキル

WBOY
WBOYオリジナル
2016-05-16 17:34:341007ブラウズ

プロトタイプチェーン:

プロトタイプを使用してプロパティとメソッドを継承します。コンストラクター、プロトタイプ、インスタンスの関係を確認します。各コンストラクターにはプロトタイプ オブジェクトを指すプロトタイプ属性があり、プロトタイプ オブジェクトには関数を指すコンストラクター属性もあり、インスタンスにはプロトタイプ オブジェクトを指す内部ポインター (__proto__) もあります。このプロトタイプ オブジェクトが別のオブジェクトのインスタンスであった場合はどうなるでしょうか?このように、プロトタイプ オブジェクトには別の型へのポインタが含まれ、同様に、他のプロトタイプにも別のコンストラクタへのポインタが含まれます。

JS の継承は非常に簡単です。つまり、サブクラスのプロトタイプを親クラスの (インスタンス化された) オブジェクトに設定します。

コードをコピー コードは次のとおりです:

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 インスタンス= new SubType() ;
alert(instance.getSuperValue()); //true

最終結果: インスタンスの __proto__ は、SubType.prototype オブジェクトと、SubType の __proto__ 属性を指します。 .prototype オブジェクト SuperType.prototype オブジェクトを指します。 getSuperValue() はメソッドであるため、プロトタイプ内にまだ存在し、property はインスタンス プロパティであるため、SubType.prototype のインスタンス内に存在します。これは、SubType.prototype が SuperType.prototype を指し、SuperType.prototype のコンストラクター プロパティが SuperType 関数を指すため、instance.constructor が SuperType を指すようになりました。

デフォルトでは、すべての参照型は Object から継承します。これは、すべての関数のプロトタイプ オブジェクトがデフォルトで Object のインスタンスであるため、内部プロトタイプ(__proto__) は Object.Prototype を指しているためです。

プロトタイプとインスタンスの関係: プロトタイプとインスタンスの関係を確認するには 2 つの方法を使用できます。
-instancef 演算子: この演算子を使用して、インスタンスとプロトタイプ チェーンに表示されるコンストラクターをテストすると、true が返されます

コードをコピーコードは次のとおりです。

alert(instance instanceof Object); //true
alert(instance instanceof SuperType); //true
alert(instance instanceof SubType); ); / /true

- isPrototypeOf() メソッド: プロトタイプ チェーンに出現するプロトタイプである限り、プロトタイプ チェーンから派生したインスタンスのプロトタイプと言えます。 。
コードをコピー コードは次のとおりです。

alert(Object.prototype.isPrototypeOf(instance) )); //true
alert(SuperType.prototype.isPrototypeOf(instance)) //true
alert(SubType.prototype.isPrototypeOf(instance)); >given クラスにメソッドを追加する場合の注意: サブクラスにメソッドを追加したり、親クラスの一部のメソッドをオーバーライドしたりすることがあります。このとき、これらのメソッドは継承後に定義する必要があることに注意してください。次の例では、SubType が SuperType を継承した後、新しいメソッド getSubValue() を追加し、getSuperValue() メソッドを書き換えます。後者の場合、SubType インスタンスのみがオーバーライドされたメソッドを使用し、SuperType インスタンスは引き続き元の getSuperValue() メソッドを使用します。


コードをコピー コードは次のとおりです。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;
};
varinstance = new SubType( );
alert(instance.getSuperValue()); //false


もう 1 つ注意すべき点は、プロトタイプ チェーンを介して継承を実装する場合、プロトタイプ メソッドを作成するのにオブジェクト リテラルを使用できないことです。プロトタイプ チェーンが上書きされるためです。以下のコードに示すように、SubType は SuperType を継承した後、オブジェクト リテラルを使用してプロトタイプにメソッドを追加します。ただし、書き換えられた SubType.prototype には Object のインスタンスが含まれるため、SubType との接続が切断されます。スーパータイプ関係。
コードをコピー コードは次のとおりです。

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()); //error!

プロトタイプ チェーンの問題: 参照型を使用する場合はプロトタイプと同じvalue 場合によっては、プロトタイプ チェーンに問題が発生することがあります。参照型値を含むプロトタイプ プロパティはすべてのインスタンスによって共有されるという前の内容を思い出してください。そのため、プロトタイプではなくコンストラクターで参照型値を定義します。プロトタイプ チェーンを通じて継承が実装されると、プロトタイプは実際には別の型のインスタンスになるため、元のインスタンスのプロパティがスムーズに現在のプロトタイプのプロパティになります。
コードをコピー コードは次のとおりです。

function SuperType(){
this .colors = ["red", "blue", "green"];
}
function SubType(){
}
//SuperType から継承
SubType.prototype = new SuperType ();
varinstance1 = new SubType();
instance1.colors.push(“black”);
alert(instance1.colors); //”赤、青、緑、黒” 🎜>varinstance2 = new SubType();
alert(instance2.colors); //"red,blue,green,black"

SuperType コンストラクターで色の配列を定義します。 , 各 SuperType インスタンスには独自の色の配列があります。ただし、SubType がプロトタイプ チェーンを使用して SuperType を継承すると、SubType.prototype は SuperType のインスタンスになるため、独自の color 属性、つまり SubType.prototype.colors 属性を持ちます。したがって、SubType インスタンスを作成すると、すべてのインスタンスがこのプロパティを共有します。上記のコードに示されているように。
2 番目の問題は、サブクラスのインスタンスを作成するときに、パラメーターをスーパークラスのコンストラクターに渡すことができないことです。実際、すべてのオブジェクト インスタンスに影響を与えずにスーパークラスのコンストラクターにパラメーターを渡す方法はないと言わなければなりません。これらの問題のため、プロトタイプ チェーンを単独で使用することはありません。

----------------------------------------------- --- ----------------------------------

コンストラクター スチール:
上記の問題を解決するために、開発者はコンストラクター スチールと呼ばれる手法を発明しました。この手法の背後にある考え方は、サブタイプ コンストラクター内でスーパータイプ コンストラクターを呼び出すことです。 (関数とは、特定の環境でコードを実行するオブジェクトにすぎませんか?) apply() メソッドまたは call() メソッドを使用して、新しく作成されたオブジェクトに対してコンストラクターを実行できます。

コードをコピー コードは次のとおりです。
function SuperType(){
this .colors = ["red", "blue", "green"];
}
function SubType(){
//SuperType から継承
SuperType.call(this);
}
varinstance1 = new SubType();
instance1.colors.push(“black”);
alert(instance1.colors) //”赤、青、緑、黒”
var instance2 = new SubType();
alert(instance2.colors); //"red, blue, green"

SubType の call() メソッドを使用して SuperType コンストラクターを呼び出します。実際には、新しい SubType オブジェクトに対して SuperType() 関数で定義されたすべてのオブジェクト初期化コードを実行します。その結果、各 SubType インスタンスには、colors プロパティの独自のコピーが存在します。
パラメーターの受け渡し: 借用したコンストラクター メソッドを使用する大きな利点は、サブクラスのコンストラクターから親クラスのコンストラクターにパラメーターを渡せることです。


コードをコピー コードは次のとおりです:

function SuperType(name){
this.name = name;
}
function SubType(){
//引数を渡す SuperType から継承
SuperType。 call(this, “Nicholas”);
//instance property
this.age = 29;
}
var instance = new SubType();
alert(instance.name); //"Nicholas";
alert(instance.age); //29

新しい SuperType コンストラクターは、SuperType パラメーター「Nicholas」を呼び出すときに、新しいパラメーター名を SuperType に追加します。 。スーパータイプ コンストラクターがサブタイプのプロパティを上書きしないようにするために、スーパータイプ コンストラクターを呼び出した後にサブクラスのプロパティを定義できます。

コンストラクターの借用に関する問題: メソッドはすべてコンストラクター内で定義されており、再利用できません。さらに、スーパータイプのプロトタイプで定義されたメソッドは、サブタイプには表示されません。その結果、すべての型はコンストラクター パターンのみを使用できます。

----------------------------------------------- --- ----------------------------------

結合継承:
プロトタイプ チェーンと借用コンストラクターの利点を組み合わせた継承パターン。プロトタイプ チェーンを使用してプロトタイプのプロパティとメソッドを継承し、借用したコンストラクターを使用してインスタンス プロパティを継承します。次の例のように、call() メソッドを使用して SuperType のコンストラクターを呼び出します (各 SubType インスタンスには独自の name 属性と color 属性、および SubType の age 属性があります)。その後、SuperType インスタンスを SubType プロトタイプに割り当てます。 SuperType のsayName() メソッドを継承させます (このメソッドは各インスタンスで共有されます)。

コードをコピー コードは次のとおりです:

function SuperType(name){
this.name = 名前;
this.colors = ["赤"、"青"、"緑"];
}

SuperType.prototype.sayName = function(){
alert(this.name);
};

function SubType(name, age){
//プロパティを継承
SuperType.call(this, name);
this.age = age;
}
//メソッドを継承
SubType.prototype = new SuperType();
SubType.prototype.sayAge = function(){
alert(this.age);
};

varinstance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
alert(instance1.colors) //"赤、青、緑、黒"
instance1.sayName(); //"Nicholas";
instance1.sayAge(); //29
var instance2 = new SubType("Greg", 27);
alert(instance2 .colors); //"赤、青、緑"
instance2.sayName(); //"グレッグ";
instance2.sayAge(); //27


プロトタイプの継承:
コードをコピー コードは次のとおりです:

関数object(o){
function F(){}
F.prototype = o;
return new F();
}
-------- -- ------------------------------------------------ -- ------------------------


寄生遺伝:

コンストラクターと同じ欠点があります

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。