javascriptの対象者向けjavascriptの継承方式を学ぶ

10346 ワード

本論文の例では、javascriptの継承を実現する6つの方法を紹介します.
1、【プロトタイプチェーン継承】実現の本質はプロトタイプオブジェクトを書き換え、新しいタイプの実例を代用することです.実はSubTypeのプロトタイプのconstructor属性が書き換えられたのではなく、SubTypeのプロトタイプが別のオブジェクト――SuperTypeのプロトタイプを指しています.このプロトタイプのconstrutor属性はSuperTypeです.

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 instance = new SubType();
alert(instance.getSuperValue());//true
【注意1】方法を慎重に定義し、原型に方法を加えるコードは、必ず原型を置き換える語句の後に置いてください.

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;
}
var instance = new SubType();
alert(instance.getSuperValue());//false

[注意2]プロトタイプチェーンによる継承は、対象の字面量を使ってプロトタイプを作成することができません.このようにするとプロトタイプチェーンを書き換えます.

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

【短所1】サブタイプのインスタンスを作成する際に、超タイプの構造関数にパラメータ[短所2]を渡すことができません.参照タイプの値を含むプロトタイプの属性はすべてのインスタンスで共有されます.

function SuperType(){
 this.colors = ['red','blue','green'];
}
function SubType(){}
//   SuperType
SubType.prototype = new SuperType();
var instance1 = new SubType();
instance1.colors.push('black');
alert(instance1.colors);//'red,blue,green,black'
var instance2 = new SubType();
alert(instance2.colors);//'red,blue,green,black'
2、【偽造の対象または古典的継承と呼ばれる構造関数の継承を借りる】サブタイプの構造関数の内部で超タイプの構造関数を呼び出すので、appy()とcall()の方法を使うことによって、将来新しく作成したオブジェクトにも構造関数を実行することができます.

function SuperType(){
 this.colors = ['red','blue','green'];
}
function SubType(){
 //   SuperType
 SuperType.call(this);
}
var instance1 = new SubType();
instance1.colors.push('black');
alert(instance1.colors);//'red,blue,green,black'
var instance2 = new SubType();
alert(instance2.colors);//'red,blue,green'
[長所]伝達パラメータ

function SuperType(name){
 this.name = name;
}
function SubType(){
 //   SUperType,        
 SuperType.call(this,"Nicholas");
 //    
 this.age = 29;
}
var instance = new SubType();
alert(instance.name);//"Nicholas"
alert(instance.age);//29 
[注意]SuperTypeコンストラクタがサブタイプの属性を書き換えないようにするために、超タイプコンストラクタを呼び出した後、サブタイプで定義すべき属性を追加することができます.

function SuperType(name){
 this.name = name;
 this.age = 30;
}
function SubType(){
 //    
 this.age = 29;
 //   SUperType,        
 SuperType.call(this,"Nicholas");
}
var instance = new SubType();
//        SuperType       
alert(instance.age);//30
【短所1】関数多重を実現できない[短所2]超タイプのプロトタイプで定義された方法は、サブタイプにとっても可視ではなく、結果として、すべてのタイプはコンストラクターモード3、【組み合わせ相続(疑似古典継承ともいう)】を使用してプロトタイプチェーンと借用構造函数の技術を組み合わせることで、2つの長さの継承モードを発揮することができます.プロトタイプ鎖を用いてプロトタイプの属性と方法の継承を実現するという考えの背後にあるが、構造関数を借りることによってインスタンス属性の継承を実現する.このように、プロトタイプ上の定義方法によって関数多重が実現されるとともに、各インスタンスに独自の属性があることが保証され、JavaScriptで最も一般的な継承モードとなる.

function SuperType(name){
 this.name = name;
 this.colors = ['red','blue','green'];
}
SuperType.prototype.sayName = function(){
 alert(this.name);
};
function SubType(name,age){
 //    
 SuperType.call(this,name);
 this.age = age;
}
//    
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
 alert(this.age);
}
var instance1 = new SubType("Nicholas",29);
instance1.colors.push("black");
alert(instance1.colors);//'red,blue,green,black'
instance1.sayName();//"Nicholas"
instance1.sayAge();//29
var instance2 = new SubType("Greg",27);
alert(instance2.colors);//'red,blue,green'
instance2.sayName();//"Greg"
instance2.sayAge();//27
【短所】サブタイプの原型を作成する時、もう一つはサブタイプの構造関数の内部にある.サブタイプは最終的にはスーパータイプのオブジェクトのすべてのインスタンス属性を含みますが、サブタイプのコンストラクタを呼び出したときにこれらの属性を書き換えなければなりません.

function SuperType(name){
 this.name = name;
 this.colors = ["red","blue","green"];
}
SuperType.prototype.sayName = function(){
 alert(this.name);
};
function SubType(name,age){
 SuperType.call(this,name); //      SuperType()
 this.age = age;
}
SubType.prototype = new SuperType(); //     SuperType()
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
 alert(this.age);
}; 
4、【プロトタイプ継承】プロトタイプによって既存のオブジェクトに基づいて新しいオブジェクトを作成することができます.本質的には、object()は、その中に入ってきたオブジェクトに対して浅い複製を実行した.【注意】原型式の継承要求は他の対象としての基礎が必要です.このような対象があれば、それをobject()関数に伝達し、具体的なニーズに応じて得られたオブジェクトを修正すればいいです.

function object(o){
  function F(){};
  F.prototype = o;
  return new F();
}
var person = {
  name: "Nicholas",
  friends: ["Shelby","Court","Van"]
};
var anotherPerson = object(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");

var yetAnotherPerson = object(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");

alert(person.friends);//"Shelby,Court,Van,Rob,Barbie"

【4.1】【Object.create()方法】:ECMAScript 5 Object.create()方法はプロトタイプ継承を規範化しました.この方法は2つのパラメータを受信する.1つは新しいオブジェクトのプロトタイプとして使用するオブジェクトと、新しいオブジェクトのために追加の属性を定義するオブジェクトである.一つのパラメータが入ってきた場合、Object.creat()は、Object()方法と同じ挙動を示します.

function object(o){
 function F(){};
 F.prototype = o;
 return new F();
}
var person = {
 name: "Nicholas",
 friends:["Shelby","Court","Van"]
};
var anotherPerson = Object.create(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");
var yetAnotherPerson = object(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");
alert(person.friends);//"Shelby,Court,Van,Rob,Barbie"
[注意]Object.create()メソッドの2番目のパラメータはObject.defineProperties()メソッドの2番目のパラメータフォーマットと同じです.各属性は自分のディスクリプタによって定義されます.このように指定した属性はいずれも原型オブジェクト上の同名属性をカバーします.

var person = {
 name: "Nicholas",
 friends:["Shelby","Court","Van"]
};
var anotherPerson = Object.create(person,{
 name: {
  value: "Greg"
 }
});
alert(anotherPerson.name);//"Greg" 
【4.2】低バージョンブラウザにおけるObject.creat()対応方法

if(typeof Object.create != "function"){
 (function(){
  var F = function(){};
  Object.create = function(o){
   if(arguments.length > 1){
    throw Error('Second argument noe supported');
   }
   if(o === null){
    throw Error("Cannot set a null [[Prototype]]");
   }
   if(typeof o != 'Object'){
    throw TypeError("Arguments must be an object");
   }
   F.prototype = o;
   return new F();
  }
 })();
} 
5、【寄生式相続】相続プロセスをカプセル化するためだけの関数を作成します.この関数は内部で何らかの方法でオブジェクトを強化し、最後に本当にすべての作業をしたように対象に戻ります.【欠点】関数多重を実現できません.

function object(o){
 function F(){};
 F.prototype = o;
 return new F();
}
function createAnother(original){
 var clone = object(original);//             
 clone.sayHi = function(){ //            
  alert("hi");
 };
 return clone;//      
}
var person = {
 name: "Nicholas",
 friends: ["Shelby","Court","Van"]
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi();//"hi"
6、【寄生結合式継承】構造関数を借りて属性を継承し、プロトタイプチェーンの混成形式で継承する方法.その背景の基本的な考え方は、サブタイプのプロトタイプを指定するために超タイプのコンストラクタを呼び出す必要はなく、必要なのは超タイププロトタイプのコピーだけです.本質的には、寄生式継承で超タイプの原型を継承し、結果をサブタイプの原型に指定します.寄生結合式継承は、引用タイプの最も理想的な継承モデルである.

//                   Super    ,        SubType.prototype        、     。    ,         。
function object(o){
 function F(){};
 F.prototype = o;
 return new F();
}
function inheritPrototype(subType,superType){
 var prototype = object(superType.prototype);//    
 prototype.constructor = subType;//    
 subType.prototype = prototype;//    
}
function SuperType(name){
 this.name = name;
 this.colors = ["red","blue","green"];
}
SuperType.prototype.sayName = function(){
 alert(this.name);
};
function SubType(name,age){
 SuperType.call(this,name);
 this.age = age;
}
inheritPrototype(SubType,SuperType);
SubType.prototype.sayAge = function(){
 alert(this.age);
}
以上は本文の全部の内容で、javascriptは継承の方式を実現して、みんなの読むことに感謝して、小さい編集は更に努力することができます!