記事はJS継承を理解しています.プロトタイプチェーン/構造関数/組み合わせ/プロトタイプ/寄生式/寄生グループ/Class extens


アリなどの大手IT企業のポストを無料で押してくれます.履歴書とWeChat angetuneを持ってきてもいいです.
正直に言うと、以前は「寄生グループ継承」が一番いいということを知っていました.最近いくつかの事のため、数週間以来ずっと心を込めて整理したいです.本文は「JavaScript高級プログラム設計」の内容を骨組みとして、ES 6クラスの関連内容を補充しました.もっと分かりやすいと思います.このことを継承して述べます.
1.継承分類
まず全体の印象を与える.図に示すように、JSでは、Object関数を使用するかどうか(以下で説明する)に従って、引き継ぎを2つの部分に分割してもよい(Object.creatはES 5によって追加された方法であり、この関数を規範化するために使用される).
その中で,プロトタイプチェーンの継承とプロトタイプの継承には同じ優れた欠点があり,構造関数の継承も寄生式の継承に対応している.寄生グループはObject.createに基づいて継承され、同時にグループの継承を最適化し、完璧な継承方式となった.ES 6クラスExtensの結果は寄生グループの引き継ぎとほぼ一致していますが、実現案は少し違っています.
これからすぐ本題に入ります.
2.継承方式
上の図の前半のプロトタイプチェーンは継承され、構造関数は継承され、組み合わせは継承され、ネット上のコンテンツは比較的多く、本論文では詳細な説明は行われない.ここでは一番分かりやすいと思う「JS中の継承」を示しています.上半区の内容に詳しくないなら、先にこの文章を読んで、また戻ってきて読み続けてもいいです.もう慣れているなら、この部分は速く省略できます.また、上半分はyqの先端の継承記事[1]を大量に借用しています.
2.1プロトタイプチェーン継承
コア:親の例をサブタイプの原型とする
SubType.prototype = new SuperType() 
//                             ,              SuperType。
SubType.prototype.constructor = SubType;
利点:親方法は欠点を多重化できる:
  • 親類の参照属性は、すべてのサブクラスインスタンスによって共有される.
  • サブクラス構成例の場合、親クラスにパラメータ
  • を渡すことができません.
    2.2構築関数継承
    コア:親構造関数の内容をサブクラスの構造関数にコピーしました.これはすべての継承の中で唯一のプロトタイプの継承に関わっていません.
    SuperType.call(SubType);
    利点:プロトタイプチェーンの継承とは完全に逆です.
  • 親類の参照属性は共有されません.
  • サブクラス構成例の場合、パラメータ
  • を親に伝えることができる.
    欠点:親の方法は多重化できません.サブクラスのインスタンスの方法は毎回個別に作成されます.
    2.3コンビネーション引継ぎ
    コア:プロトタイプ継承と構造関数継承の組み合わせは、両者の利点を兼ね備えています.
    function SuperType() {
        this.name = 'parent';
        this.arr = [1, 2, 3];
    }
    
    SuperType.prototype.say = function() { 
        console.log('this is parent')
    }
    
    function SubType() {
        SuperType.call(this) //      SuperType
    }
    
    SubType.prototype = new SuperType() //      SuperType
    利点:
  • 親タイプの方法は、
  • を多重化することができる.
  • 親類の参照属性は共有されません.
  • サブクラス構成例の場合、パラメータ
  • を親に伝えることができる.
    短所:2回の父類の構造関数を呼び出して、初めてサブクラスの原型に父類のname、arr属性を追加しました.2回目にはサブクラスの構造関数に父類のname、arr属性を追加して、サブタイプの原型の同名パラメータをカバーしました.このカバーされた状況は性能上の浪費をもたらした.
    2.4原型式継承
    コア:プロトタイプ継承の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"
    
    ECMAScript 5はObject.create()を追加することによりプロトタイプ継承を規範化した.この方法は2つのパラメータを受信する.1つは新しいオブジェクトのプロトタイプとして使用するオブジェクトと、新しいオブジェクトのために追加の属性を定義するオブジェクトである.一つのパラメータが導入された場合、Object.create()は、Object()方法の動作と同じである.『JAVALSCRIpt高級プログラミング』
    したがって、上記のコードは
    var yetAnotherPerson = object(person); => var yetAnotherPerson = Object.create(person);
    2.5寄生式引継ぎ
    コア:プロトタイプ継承を使用してターゲットオブジェクトの浅いコピーを取得し、この浅いコピーの能力を強化します.長所と短所:一つの考えだけを提供しても、長所はあまりないです.
    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"
    2.6寄生グループ引き継ぎ
    先の話ですが、父のような構造関数を2回呼び出して無駄にしてしまうという欠点があります.寄生グループの継承はこの問題を解決することができます.
    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);
    }
    長所と短所:これは完璧な継承方式です.
    2.7 ES 6クラスextens
    コア:ES 6継承の結果は寄生グループ継承と似ていますが、本質的にはES 6継承はシンタックスキャンディーです.しかし、寄生結合継承は、サブクラスのインスタンスthisオブジェクトを作成してから強化される.ES 6は、最初に親のインスタンスオブジェクトの属性と方法を、thisの上に加え(従って、Superメソッドを呼び出す必要があります)、その後、サブクラスの構造関数でthisを修正します.
    class A {}
    
    class B extends A {
      constructor() {
        super();
      }
    }
    ES 6継承の具体的な原理:
    class A {
    }
    
    class B {
    }
    
    Object.setPrototypeOf = function (obj, proto) {
      obj.__proto__ = proto;
      return obj;
    }
    
    // B       A    
    Object.setPrototypeOf(B.prototype, A.prototype);
    
    // B    A      
    Object.setPrototypeOf(B, A);
    
    ES 6継承とES 5継承の違い:同じ点:本質的にES 6継承はES 5継承のシンタックス飴の違い:
  • ES 6は中性子類の構造関数のプロトタイプチェーンを継承し、父類の構造関数を指す.ES 5では構造関数コピーを使用し、プロトタイプチェーン指向がない.
  • ES 6サブクラスのインスタンスの構築は、親のインスタンスに基づいて、ES 5ではない.
  • 3.まとめ
  • ES 6クラスextendsはES 5が継承するシンタックス糖です.
  • JSの継承は、構造関数の継承に加えて、プロトタイプチェーンに基づいて構築された
  • である.
  • は寄生グループでES 6クラスextensを継承することができますが、まだ微妙な違いがあります.
    参考記事:
    [1]『js継承、構造関数継承、プロトタイプチェーン継承、組合せ継承最適化、寄生組合せ継承』〔2〕『JavaScript高級プログラミング』