JS相続の概念
JSで一般的に使用される次の2つの継承方法:
プロトタイプチェーン継承(オブジェクト間の継承)
古典的継承(コンストラクター間の継承)
JSはJavaのような真のオブジェクト指向の言語ではないため、JSはオブジェクトベースであり、クラスの概念はありません。したがって、継承を実装する場合は、JSのプロトタイププロトタイプメカニズムを使用するか、ApplyおよびCall Methodを使用して実装できます。
オブジェクト指向の言語では、クラスを使用してカスタムオブジェクトを作成します。ただし、JSのすべてはオブジェクトであるため、カスタムオブジェクトを作成するためにどのような方法を使用できますか?これにはJSプロトタイプが必要です。
単にプロトタイプをテンプレートと見なすことができます。新しく作成されたカスタムオブジェクトは、このテンプレート(プロトタイプ)のコピーです(実際にはコピーではなくリンクですが、この種のリンクは目に見えません。新しくインスタンス化されたオブジェクトの内部には、プロトタイプオブジェクトを指す目に見えない__Proto__ポインターがあります)。
JSは、コンストラクターとプロトタイプを介してクラスの機能をシミュレートして実装できます。さらに、JSタイプの継承の実装は、プロトタイプチェーンに依存することによっても達成されます。
プロトタイプの継承とクラスの継承
古典的継承は、サブタイプコンストラクター内のスーパータイプコンストラクターの呼び出しです。
厳格なクラスの継承はあまり一般的ではなく、一般的に組み合わせて使用されます。
コードコピーは次のとおりです。
関数super(){
this.colors = ["red"、 "blue"];
}
function sub(){
super.call(this);
}
プロトタイプの継承は、既存のオブジェクトの助けを借りて新しいオブジェクトを作成し、サブクラスのプロトタイプを親クラスに向けることです。これは、親クラスのプロトタイプチェーンを追加するのと同等です。
プロトタイプチェーンの継承
子クラスが親クラス(方法を含む)の特性を継承するためには、最初に定義するためにコンストラクターが必要です。次に、コンストラクターのプロトタイプに親クラスの新しいインスタンスを割り当てます。コードは次のとおりです。
コードコピーは次のとおりです。
<スクリプト>
function parent(){
this.name = 'mike';
}
function child(){
this.age = 12;
}
child.prototype = new Parent(); //子は親を継承し、プロトタイプを介してチェーンを形成します。
var test = new Child();
アラート(test.age);
alert(test.name); //継承属性を取得します
//プロトタイプチェーンを継承し続けます
function brother(){// Brother construct
this.weight = 60;
}
brother.prototype = new Child(); //プロトタイプチェーン継承を続けます
var Brother = new Brother();
alert(brother.name); //親と子を継承する、マイクがポップアップします
Alert(Brother.age); // pop 12
</script>
上記のプロトタイプチェーンの継承には、オブジェクトである1つのリンクがまだ1つありません。すべてのコンストラクターはオブジェクトから継承されます。継承オブジェクトは自動的に完了し、自分で手動継承を必要としません。それで、彼らの下位の関係は何ですか?
プロトタイプとインスタンスの関係を決定します
プロトタイプとインスタンスの関係を決定するには、2つの方法があります。オペレーターInstanceOFおよびISPrototypeof()メソッド:
コードコピーは次のとおりです。
アラート(兄弟instanceof object)// true
アラート(兄弟のテストインスタンス); // false、テストは兄弟のスーパークラスです
アラート(子供の兄弟インスタンス); // true
アラート(親の兄弟インスタンス); // true
プロトタイプチェーンに表示されるプロトタイプである限り、プロトタイプチェーンから派生したインスタンスのプロトタイプであると言えます。したがって、ISPrototypeof()メソッドもtrueを返します。
JSでは、継承された関数はスーパータイプ(親クラス、ベースクラス、およびまた)と呼ばれ、継承された関数はサブタイプ(サブクラス、派生クラス)と呼ばれます。プロトタイプの継承を使用するには、主に2つの問題が含まれます。
まず、プロトタイプの文字通りの書き換えは関係を破り、参照タイプのプロトタイプを使用し、サブタイプはパラメーターをスーパータイプに渡すことができません。
擬似クラスは、参照共有の問題と、引数に合格することができないスーパータイプの問題を解決します。 「コンストラクター」テクノロジーを使用できます。
借入コンストラクター(古典的継承)
コードコピーは次のとおりです。
<スクリプト>
関数の親(年齢){
this.name = ['Mike'、 'Jack'、 'Smith'];
this.age = age;
}
function child(age){
parent.call(これ、年齢);
}
var test = new Child(21);
アラート(test.age); // 21
アラート(test.name); //マイク、ジャック、スミス
test.name.push( 'bill');
アラート(test.name); //マイク、ジャック、スミス、ビル
</script>
借用コンストラクターは現在2つの問題を解決しましたが、プロトタイプなしでは再利用する方法はありません。そのため、プロトタイプチェーン +借入コンストラクターパターンが必要です。このパターンは、組み合わせ継承と呼ばれます。
組み合わせ継承
コードコピーは次のとおりです。
<スクリプト>
関数の親(年齢){
this.name = ['Mike'、 'Jack'、 'Smith'];
this.age = age;
}
parent.prototype.run = function(){
this.name + 'は両方とも' + this.ageです。
};
function child(age){
parent.call(this、age); //オブジェクトはパラメーターになりすまし、スーパータイプに渡します
}
child.prototype = new Parent(); //プロトタイプチェーン継承
var test = new Child(21); //新しい親(21)を書くのは大丈夫です
alert(test.run()); //マイク、ジャック、スミスは両方21です
</script>
併用継承は、比較的一般的に使用される継承方法です。その背後にあるアイデアは、プロトタイプチェーンを使用してプロトタイプの特性と方法の継承を実装し、コンストラクターを借用することによりインスタンスプロパティの継承を実装することです。このようにして、プロトタイプのメソッドを定義し、各インスタンスに独自の特性があることを確認することにより、関数の多重化が達成されます。
call()の使用法:オブジェクトのメソッドを呼び出し、現在のオブジェクトを別のオブジェクトに置き換えます。
コードコピーは次のとおりです。
call([thisobj [、arg1] [、arg2 [、[、.argn]]]]])
プロトタイプの継承
カスタムタイプを作成せずに既存のオブジェクトに基づいて新しいオブジェクトの作成を継承するこの方法は、プロトタイプ継承と呼ばれます
コードコピーは次のとおりです。
<スクリプト>
関数obj(o){
関数f(){}
f.prototype = o;
新しいf()を返します。
}
var box = {
名前: 'trigkit4'、
arr:['brother'、 'sister'、 'baba']
};
var b1 = obj(box);
アラート(b1.name); // trigkit4
b1.name = 'mike';
アラート(b1.name); // mike
アラート(b1.arr); //兄弟、姉妹、ババ
b1.arr.push( 'parents');
アラート(b1.arr); //兄弟、姉妹、ババ、両親
var b2 = obj(box);
アラート(b2.name); // trigkit4
アラート(b2.arr); //兄弟、姉妹、ババ、両親
</script>
プロトタイプ継承は、最初にOBJ()関数内に一時的なコンストラクターを作成し、次に渡されたオブジェクトをコンストラクターのプロトタイプとして使用し、最後にこの一時的なタイプの新しいインスタンスを返します。
寄生性継承
この継承方法は、プロトタイプ +工場モデルを組み合わせて、カプセル化作成プロセスを目的としています。
コードコピーは次のとおりです。
<スクリプト>
関数create(o){
var f = obj(o);
f.run = function(){
this.arr; //同様に、参照が共有されます
};
fを返します。
}
</script>
組み合わせ継承に関する小さな問題
併用継承はJSで最も一般的に使用される継承モードですが、使用中に2回呼び出されます。かつてはサブタイプを作成するときで、もう1つはサブタイプコンストラクター内にあります。
コードコピーは次のとおりです。
<スクリプト>
function parent(name){
this.name = name;
this.arr = ['brother'、 'sister'、 'parents'];
}
parent.prototype.run = function(){
this.nameを返します。
};
function child(name、age){
parent.call(this、age); // 2番目の呼び出し
this.age = age;
}
child.prototype = new Parent(); //最初の呼び出し
</script>
上記のコードは以前の組み合わせ継承であるため、寄生的な組み合わせ継承は2つの呼び出しの問題を解決します。
寄生的な組み合わせ継承
コードコピーは次のとおりです。
<スクリプト>
関数obj(o){
関数f(){}
f.prototype = o;
新しいf()を返します。
}
関数create(親、テスト){
var f = obj(parent.prototype); //オブジェクトを作成します
f.constructor = test; //拡張オブジェクト
}
function parent(name){
this.name = name;
this.arr = ['brother'、 'sister'、 'parents'];
}
parent.prototype.run = function(){
this.nameを返します。
};
function child(name、age){
parent.call(this、name);
this.age = age;
}
継承プロトタイプ(親、子); //継承はここから実現されます
var test = new Child( 'trigkit4'、21);
test.arr.push( 'nephew');
アラート(test.arr); //
alert(test.run()); //メソッドのみが共有されます
var test2 = new Child( 'Jack'、22);
アラート(test2.arr); //引用の問題を解決します
</script>
電話して応募してください
グローバル関数が適用され、呼び出しを使用して、次のように関数のこれのポインティングを変更できます。
コードコピーは次のとおりです。
//グローバル関数を定義します
function foo(){
console.log(this.fruit);
}
//グローバル変数を定義します
var fruit = "apple";
//オブジェクトをカスタマイズします
var pack = {
果物:「オレンジ」
};
// window.foo()に相当します。
foo.apply(window); //「Apple」、これはウィンドウに等しい
// foo in this === pack
foo.apply(pack); // "オレンジ"