導入
プログラミングはコードの再利用を提案します。それ以外の場合は、新しいプログラムを開発するか、新しい機能を作成するたびに新しいプログラムを作成する必要がある場合は、無駄になります。ただし、コードの再利用も良いか悪いことです。次の2つの記事では、コードの再利用について説明します。最初の記事は、これらのパターンの使用を可能な限り回避します。 2番目の行は推奨です。これは、誰もが使用する推奨パターンを指し、一般的に問題はありません。
モード1:デフォルトモード
多くの場合、すべての人が一般的に使用するデフォルトモードのコード再利用に問題があります。このモードは、Parent()のコンストラクターを使用してオブジェクトを作成し、オブジェクトを子()プロトタイプに割り当てます。コードを見てみましょう:
コードコピーは次のとおりです。
関数継承(c、p){
c.prototype = new P();
}
//親コンストラクター
function parent(name){
this.name = name || 'アダム';
}
//プロトタイプに関数を追加します
parent.prototype.say = function(){
this.nameを返します。
};
//子コンストラクターは空です
function child(name){
}
//継承を実行します
相続(子、親);
var kid = new Child();
console.log(kid.say()); //「アダム」
var kiddo = new Child();
kiddo.name = "patrick";
console.log(kiddo.say()); //「パトリック」
//短所:パラメーターを子コンストラクターに渡すことはできません
var s = new Child( 'seth');
console.log(s.say()); //「アダム」
このモードの欠点は、子供がパラメーターを渡すことができないことです。これは基本的に役に立たないことです。
パターン2:コンストラクターの借入
このパターンは、子供が親のコンストラクターを貸し出して適用し、子供のこれとパラメーターを適用方法に合格することです。
コードコピーは次のとおりです。
//親コンストラクター
function parent(name){
this.name = name || 'アダム';
}
//プロトタイプに関数を追加します
parent.prototype.say = function(){
this.nameを返します。
};
//子コンストラクター
function child(name){
parent.Apply(これ、引数);
}
var kid = new Child( "Patrick");
console.log(kid.name); //「パトリック」
//短所:SAYメソッドはコンストラクターから継承されていません
console.log(typeof kid.say); // "未定義"
欠点も明らかであり、SAYメソッドは継承されていないため利用できません。
パターン3:コンストラクターを借りて、プロトタイプを設定します
上記の2つのモードには独自の欠点があるので、両方の欠点を削除するにはどうすればよいですか?試してみましょう:
コードコピーは次のとおりです。
//親コンストラクター
function parent(name){
this.name = name || 'アダム';
}
//プロトタイプに関数を追加します
parent.prototype.say = function(){
this.nameを返します。
};
//子コンストラクター
function child(name){
parent.Apply(これ、引数);
}
child.prototype = new Parent();
var kid = new Child( "Patrick");
console.log(kid.name); //「パトリック」
console.log(typeof kid.say); // 関数
console.log(kid.say()); //パトリック
console.dir(kid);
kid.nameを削除;
console.log(kid.say()); //「アダム」
実行すると、すべてが正常ですが、親コンストラクターが2回実行されていることに気づいたので、プログラムは利用できますが、非常に非効率的です。
モード4:共有プロトタイプ
共有プロトタイプとは、子と親が同じプロトタイプを使用することを意味します。コードは次のとおりです。
コードコピーは次のとおりです。
関数継承(c、p){
c.prototype = p.prototype;
}
//親コンストラクター
function parent(name){
this.name = name || 'アダム';
}
//プロトタイプに関数を追加します
parent.prototype.say = function(){
this.nameを返します。
};
//子コンストラクター
function child(name){
}
相続(子、親);
var kid = new Child( 'patrick');
console.log(kid.name); // 未定義
console.log(typeof kid.say); // 関数
kid.name = 'patrick';
console.log(kid.say()); //パトリック
console.dir(kid);
同じことが真実であることは確かであり、子供のパラメーターは正しく受信されません。
パターン5:一時的なコンストラクター
まず、コンストラクターを借りてから、子供のプロトタイプを借りたコンストラクターのインスタンスに設定し、最後に子供のプロトタイプのコンストラクターを復元します。コードは次のとおりです。
コードコピーは次のとおりです。
/*閉鎖*/
var enternit =(function(){
var f = function(){
};
return function(c、p){
f.prototype = p.prototype;
c.prototype = new f();
c.uber = p.prototype;
c.prototype.constructor = c;
}
}());
function parent(name){
this.name = name || 'アダム';
}
//プロトタイプに関数を追加します
parent.prototype.say = function(){
this.nameを返します。
};
//子コンストラクター
function child(name){
}
相続(子、親);
var kid = new Child();
console.log(kid.name); // 未定義
console.log(typeof kid.say); // 関数
kid.name = 'patrick';
console.log(kid.say()); //パトリック
var kid2 = new Child( "Tom");
console.log(kid.say());
console.log(kid.constructor.name); // 子供
console.log(kid.constructor === parent); // 間違い
問題はまだ同じです。子供は通常パラメーターを受け取ることができません。
モード6:Klass
このパターンのコードから始めましょう。
コードコピーは次のとおりです。
var klass = function(parent、props){
var child、f、i;
// 1。
//新しいコンストラクター
child = function(){
if(child.uber && child.uber.hasownproperty( "__ construct")){
child.uber .__ construct.apply(this、arguments);
}
if(child.prototype.hasownproperty( "__ construct")){
child.prototype .__ construct.apply(this、arguments);
}
};
// 2。
// 継承
親=親||物体;
f = function(){
};
f.prototype = parent.prototype;
child.prototype = new f();
child.uber = parent.prototype;
child.prototype.constructor = child;
// 3。
//実装方法を追加します
(私は小道具で){
if(props.hasownProperty(i)){
child.prototype [i] = props [i];
}
}
//「クラス」を返します
子供を返します。
};
var man = klass(null、{
__construct:function(what){
console.log( "Man's Constructor");
this.name = what;
}、
getName:function(){
this.nameを返します。
}
});
var first = new Man( 'Adam'); //「男のコンストラクター」を記録します
first.getname(); //「アダム」
var superman = klass(man、{
__construct:function(what){
console.log( "Superman's Constructor");
}、
getName:function(){
var name = superman.uber.getname.call(this);
「I Am」 +名前を返します。
}
});
Var Clark = New Superman( 'Clark Kent');
clark.getName(); //「私はクラーク・ケントです」
Console.log(Clark Instanceof Man); // 真実
console.log(clark instanceof superman); // 真実
それはどうですか?見るのは少しめまいですか?良いために、このパターンの文法と仕様は他の言語と同じです。あなたはそれを使っても構わないと思っていますか?咳。 。 。
要約します
上記の6つのモードは特定の特別な状況で特定の機能を実装していますが、それらはすべて独自の欠点を持っているため、一般的に、誰もがそれらを使用することを避ける必要があります。