ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScriptの継承について詳しく解説

JavaScriptの継承について詳しく解説

黄舟
黄舟オリジナル
2017-02-27 14:37:581312ブラウズ

js の継承について正式に議論する前に、まず私の職歴について話させてください。バックエンドとは異なり、ほとんどの商用アプリケーションのシナリオでは、フロントエンドの要件により、コードのトレースが困難になることがよくあります (つまり、抽象化が難しく、コードを一度記述するだけで複数のコードに適用できるという意味です)。シナリオ)。私がよく知っているアプリケーション シナリオについて話しましょう。たとえば、信用格付けモジュールでは、あるページでは折れ線グラフを使用してユーザーの最近の消費レベルを表示し、別のページでは折れ線グラフを使用してユーザーの信用格付けレベルを表示します。非常に似たようなニーズがあるように思えますよね? Javaで取得すると必ず「折れ線グラフのインターフェース」を抽象化しますが、それをjsで統一するのは難しいです。まず、2 つのデータ ソースが異なるため、ajax リクエスト コードも大きく異なります。次に、UI が画像に影やグラデーションなどのグラフィック効果をランダムに追加する場合、2 つの画像の実装は完全に異なります。それだけでなく、設計レベルを示すために 2 つの異なるフロントエンド実装を強制的に統合すると、一般の人が直面することのないメンテナンスの悪夢に直面することになります。したがって、ほとんどのフロントエンド エンジニアにとって、JavaScript の継承を理解する必要はありません。また、この言語のこの機能には、あまり一般的なアプリケーション シナリオがありません。もちろん、基礎となるフレームワークを作成している場合は、これらのことを確実に知っているでしょう。機能は非常に良いです。以下の内容は、「JavaScript による上級プログラミング」の継承を少し書き直したもので、時間があるときに継承モデルの最適化されたバージョンを追加します。興味がなければそのまま読んでください ~


(1)組み合わせ継承(組み合わせ継承):

親クラスの属性を追加します。サブクラス コンストラクターの Super.call(this) を介して、サブクラス コンストラクターの prototype を親クラスのインスタンスにして継承を実現します。欠点は、冗長な親クラスのプロパティがサブクラスのコンストラクターに格納され (これは親クラスのインスタンスであり、サブクラスのインスタンスが同じプロパティを上書きするため)、親クラスのコンストラクターが 2 回呼び出されることになります。また、継承チェーンにもう 1 つの層ができます。


(function combineInherit(){
   function SuperType(){
      this.super="super";
   }
   SuperType.prototype.saySuper=function(){

   }

   function SubType(){
      SuperType.call(this,arguments);
      this.sub="sub";
   }
   SubType.prototype=new SuperType();
   SubType.prototype.constructor=SubType;
   SubType.prototype.saySub=function(){

   }

   var sub1=new SubType();
   sub1.saySub();
})();


継承チェーン:

(2) 寄生組み合わせ継承 (寄生組み合わせ継承):

と組み合わせ継承の違いは、寄生要素が組み合わせられることです。別のサブクラス コンストラクターの プロトタイプ を継承しても、親クラスのインスタンスにはなりませんが、親クラス コンストラクターの プロトタイプ の参照を直接使用して、サブクラス コンストラクターの プロトタイプ を形成します。これは最も合理化された方法です。つまり、他の 2 つは直接同等です。これにより、親クラスのコンストラクターへの呼び出しが減るだけでなく、サブクラス prototype 内の冗長な属性も減り、継承の層も減ります。 chain (そしてこの場合、同じサブクラスと親クラスに属する instanceof判定を使用します)。

(function parasiticCombineInherit(){
   function inheritPrototype(subType,superType){
      subType.prototype=superType.prototype;
      subType.prototype.constructor=subType;
   }

   function SuperType(){
      this.super="super";
   }
   SuperType.prototype.saySuper=function(){

   }

   function SubType(){
      SuperType.call(this,arguments);
      this.sub="sub";
   }
   inheritPrototype(SubType,SuperType);
   SubType.prototype.saySub=function(){

   }

   var sub=new SubType();
   console.log(sub instanceof SuperType);
})();


継承チェーン:

(3)jQUeryスタイルの古典的な継承


(function classicInherit(){
   var initializing=false,
      superPattern=/xyz/.test(function() {xyz;}) ? /\b_super\b/ : /.*/;
   Object.subClass=function(properties){
      var _super=this.prototype;
      initializing=true;
      var proto=new this();
      initializing=false;

      for(var name in properties){
         proto[name]=typeof properties[name]=="function"&&
                  typeof _super[name]=="function"&&
                  superPattern.test(properties[name])?
               (function(name,fn){
                  return function(){
                     var tmp=this._super;
                     this._super=_super[name];
                     var ret=fn.apply(this,arguments);
                     this._super=tmp;
                     return ret;
                  };
               })(name,properties[name]):properties[name];
      }

      function Class(){
         //init方法需要通过外部自定义传入
         if(!initializing&&this.init){
            this.init.apply(this,arguments);
         }
      }
      Class.prototype=proto;
      Class.constructor=Class;
      Class.subClass=arguments.callee;

      return Class;
   }
})();

上記は JavaScript の継承の詳細な説明です。詳細については、PHP 中国語 Web サイト (www.php.cn) をフォローしてください。



声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。