JavaScriptにおける継承の寄生組み合わせ式継承

2834 ワード

まずグループ継承について話します.最も一般的な継承方式の組み合わせで継承されているが、その最大の問題は、どのような場合でも2回の超構造関数を呼び出すことである.1回はサブタイプの原型を作成する時、もう1回はサブタイプの構造関数の内部にある.
組合せ継承はプロトタイプ継承法とプロトタイプ属性によって構成関数がインスタンス属性を継承します.しかし、サブクラスは、プロトタイプによって、超タイプのすべてのインスタンス属性を継承しています.すなわち、スーパークラスのインスタンス属性は、サブクラスのプロトタイプ属性となります.したがって、サブクラスのコンストラクタを呼び出したときに、これらの属性を書き換えなければなりません.つまり、サブクラスのプロトタイプオブジェクトに超クラスからのインスタンス属性を継承するのは、全く余分です.
一つのグループの引き継ぎの例を見ます.
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);
};

var instance = new SubType('Greg',39);     //  SubType    ,      
instance.colors.push('black');      //      
SuperTypeコンストラクターを初めて呼び出した時、SubTypeは二つの属性を得て、nameとcolors(この二つはプロトタイプで継承された属性は余分です).instanceの例を作成してSubTypeのコンストラクタを呼び出すと、再度SuperTypeのコンストラクターを呼び出します.今回は新しいオブジェクトにインスタンス属性nameとColorsを作成しました.つまり、プロトタイプの属性を書き換えて、プロトタイプの中の二つの同名属性を遮断しました.
このような二回の超構造関数の呼び出しを避けるために,サブクラスのプロトタイプオブジェクトに余分な特性の欠陥を創建し,寄生結合式継承を用いることができる.
寄生グループ式継承とは?すなわち,構造関数を用いて属性を継承し,プロトタイプ鎖の混成によって方法を継承した.
基本的な考え方は、サブタイプのプロトタイプを指定するためにコンストラクタを呼び出す必要がないということです.私たちが必要なのは超タイプのコピーにすぎません.本質的には、寄生式継承を用いて超タイプの原型を継承し、結果をサブタイプの原型に指定します.
基本パターンは以下の通りです.
やはり前のobject関数を使います.
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;    //    
}
この関数は2つのパラメータ、サブ構造関数、および超構造関数を受信します.関数内部では、第1ステップで超種類の原型オブジェクトのコピーを作成し、第2ステップではコピーにconstrutor属性を追加し、subTypeを指し、元のモデルを書き換えることによってデフォルトのconstructor属性を失うことを補う.最後のステップは、コピーをサブタイプのプロトタイプに割り当てます.プロセス全体で言う簡単な点は、超クラスの原型オブジェクトの一つのコピーをサブクラスの原型オブジェクトにコピーすることです.このようにすると、超クラスの実例的な属性の継承を避けることができます.つまり、サブクラスの原型オブジェクトに余分な属性の作成を避けることができます.もう一つ例をあげます.
function superType(name){
    this.name = namel
    this.colors = ['red','blue','yellow'];
}

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);
}
この例の高効率化は、一回のsuperType構造関数のみを呼び出し、subType.prototypeに不必要な属性を作成することを回避するために実行される.これと同時に、プロトタイプチェーンは変わらないので、instance of()とisPrototypeOf()を正常に使うことができます.寄生式の組合せ継承は、引用タイプの最も理想的な継承モデルである.