ここでの継承の概念がいかに単純であるかがわかります。「あるクラスのプロトタイプを別のクラスにコピーする」ということです。コードは簡単です。コードを見てください。
function class1() { }
function class2() { }
class2.prototype = class1.prototype;
class2.moreProperty1 = " クラス 2 追加文字列 " ;
class2.moreMethod1 = function () { alter( " クラス 2 追加メソッド " ) ; }
/*
このように、まず、class2 は、コンストラクターに関係なく、class1 と同じプロトタイプを持ちます。
その後、プロトタイプを通じて 2 つの追加メソッドが class2 に与えられました。そこで、class2 は class1
をベースに属性とメソッドを追加し、クラスの継承を実現します。
*/
function test() {
var obj = new class2();
// JavaScript は、オブジェクトが特定のクラスのインスタンスであるかどうかを判断する instanceof 演算子を提供します
alert(objinstanceofclass2); // true
alert(objinstanceofclass1); // ?
}
結果は期待どおりですか?表面的には、上記の実装は完全に実現可能であり、js もこの継承関係を正しく理解して実装できます。obj は class1 と class2 の両方のインスタンスですが、実際にはそうではありません (私たちの研究の目的は、それについて詳しく知ることです。それ)その理由)。この js の理解は、実際には非常に単純な戦略に基づいています。最初にプロトタイプを使用して class2 を class1 から継承させ、次に class2 でメソッドを繰り返し定義します。
// Define class1
function class1() {
//Constructor
}
// class1 のメンバーを定義
class1.prototype = {
m1: function () { // メソッド 1
alert( " class1 method1 " );
}
}
// クラス 2 を定義します
関数 class2() {
// コンストラクター
}
// クラス 2 を継承させますclass1
class2.prototype = class1.prototype;
// class2 のメソッドメソッドを繰り返し定義
class2.prototype.method = function () {
alert( " 誰のメソッド 2? class1 またはclass2 " );
}
// 2 つのクラスのインスタンスを作成します
var obj1 = new class1();
var obj2 = new class2();
function test() {
// 2 つのオブジェクトのメソッドをそれぞれ呼び出します
obj1.method();
obj2.method();
}
コードの実行結果から判断すると、 class1 と class2 で実行されたメソッドの結果は同じです。
class2 のプロトタイプが変更されると、それに応じて class1 のプロトタイプも変更され、class2 のプロトタイプにメンバーが追加または削除された場合でも、それに応じて class1 のメンバーも変更されることがわかります。 。したがって、class1 と class2 は、異なるコンストラクターを持つ単なる 2 つのクラスですが、同じメンバー定義を維持します。この時点で、読者はその秘密を発見したと思います。class1 と class2 のプロトタイプはまったく同じであり、同じオブジェクトを参照しています。実際、次の代入ステートメントからわかります。
//class2 を class1 から継承させます。
class2.prototype=class1.prototype;
js では、基本的なデータ型 (数値、文字列、ブール型など)、すべての代入と関数パラメータは値ではなく参照によって渡されます。したがって、上記のステートメントは、class2 のプロトタイプ オブジェクトが class1 のプロトタイプを参照することのみを許可し、その結果、クラス メンバーの定義が常に一貫しているという効果が得られます。ここからは、オブジェクトがプロトタイプのインスタンスであるかどうかを判断する、instanceof オペレーターの実行メカニズムもわかります。ここでは、obj1 と obj2 は同じプロトタイプに対応するため、instanceof の結果は同じになります。プロトタイプ参照コピーを使用して継承を実装するのは正しい方法ではないことがわかります。ただし、要件が厳しくない場合、これは合理的な方法でもあります。唯一の制約は、クラス メンバーの定義のオーバーライドが許可されていないことです (これは実際には js の柔軟性を反映しています)。実際、リフレクション メカニズムとプロトタイプを完全に使用して、JS で正しいクラス継承を実現できます。
function class1() {
// Constructor
}
class1.prototype = {
メソッド: 関数 () {
アラート( " メソッド 1 " );
},
メソッド 2: 関数 () {
アラート( " メソッド 2 " );
}
function class2() {
// コンストラクター
}
// class2 に class1 を継承させます
for ( var p in class1.prototype) {
class2.prototype [p] = class1.prototype[p]; //リフレクション機構とプロトタイプを使用して継承を実装します
}
// class1
class2.prototype.method = function で定義されたメソッドをオーバーライドします( ) {
alert( " class2 new Method1 " );
}
// 2 つのクラスのインスタンスを作成します
var obj1 = new class1(); obj2 = new class2();
function test() {
// 2 つのオブジェクトのメソッドをそれぞれ呼び出します
obj1.method();
obj2.method();
// 2 つのオブジェクトのメソッド 2 メソッドをそれぞれ呼び出します。
obj1.method2();
obj2.method2();
}
実行結果からわかります。 obj2 メソッドで繰り返された定義により、継承されたメソッドがオーバーライドされますが、method2 メソッドは影響を受けません。そして、obj1 のメソッドメソッドは元の定義を維持しています。このようにして、クラス継承の正しい意味が実現されます。開発を容易にするために、各クラスに共通のメソッドを追加してクラスの継承を実装できます。
// 静的メソッドの継承をクラスに追加して、特定のクラスからの継承を示します
Function.prototype。継承 = function (baseClass) {
for ( var p inbaseClass.prototype) {
this .prototype[p] =baseClass.prototype[p]
}
}
function class1() {
//Constructor
}
class1.prototype = {
method: function () {
alert( " method1 " ), method2: function () {
alert( " method2 " );
}
}
function class2() {
// コンストラクター
}
/ / class2 を class1 から継承させます
// for (var p in class1.prototype) {
// class2.prototype[p] = class1.prototype[p] // リフレクション メカニズムとプロトタイプを使用して継承を実現します。
// }
class2.inherit(class1); // 上記でコメントアウトされた for ループと同等
// class1
class2 .prototype で定義されたメソッドをオーバーライドします。 Method = function () {
alert( " class2 new method1 " );
// 2 つのクラスのインスタンスを作成します
var obj1 = new class1 (); 🎜>var obj2 = new class2();
function test() {
// 2 つのオブジェクトのメソッドをそれぞれ呼び出します
obj1.method(); ();
// 2 つのオブジェクトのメソッド 2 メソッドをそれぞれ呼び出します
obj1.method2();
}
上記のコードそして理解しやすくなります。このメソッドで実装された継承の欠点の 1 つは、class2 にクラス メンバー定義を追加するときに、プロトタイプに値を直接割り当てることはできず、その属性にのみ値を割り当てることができることです。たとえば、
のようにすることはできません。 class2.prototype={
//メンバー定義
}
それは次のとおりです:
class2.prototype.propertyName=someValue;
class2.prototype.methodName=function(){
//Statement
}
この方法で継承を実装しても、コードの可読性がある程度犠牲になることがわかります。 「基本クラスがオブジェクトをプロパティに直接割り当てるだけでなく、派生クラスにも実装できるため、コード ロジックがより明確になり、オブジェクト指向言語の特性をよりよく反映できる」js 継承メソッドはありますか?引用符で囲まれたことわざはとても魅力的ですので、勉強を続けてください。