3.JS設計モードと開発実践抜粋(一)

8284 ワード

1.データのパッケージ
  • 多くの言語の対象システムにおいて、パッケージデータは構文解析によって実現され、これらの言語はprvate、public、protectedなどのキーワードを提供して、異なるアクセス権限を提供するかもしれない.しかし、JavaScriptはこれらのキーワードに対するサポートを提供していません.私たちは変数の作用領域に依存してパッケージの特性を実現するしかありません.
  • //   ES6    let   ,              
    var myObject = (function() {
       //     
       var _name = 'sven';
      //    public  
       return {
          getName: function () {
              return _name;
          }
       }
    })()
    console.log( myObject.getName() ); //   :sven
    console.log( myObject.__name ) //   :undefined
    
    2.クローンを使ったプロトタイプ
  • は、従来のクラスとは違って、まずクラスのインスタンスを作成し、その後、この例に属性と方法を追加したい.
  • モデルの実現の鍵は、言語自体がclone方法を提供しているかどうかである.ECMAScript 5はObject.create方法を提供しており、オブジェクトをクローンするために使用できます.コードは以下の通りです.
  • var Plane = function () {
        this.blood = 100;
        this.attackLevel = 1;
        this.defenseLevel = 1;
    };
    var plane = new Plane();
    plane.blood = 500;
    plane.attackLevel = 10;
    plane.defenseLevel = 7;
    
    var clonePlane = Object.create( plane );
    console.log( clonePlane ); //   :Object {blood: 500, attackLevel: 10, defenseLevel: 7}
    //     Object.create        ,         :
    Object.create = Object.create || function( obj ){
       var F = function(){};
       F.prototype = obj;
       return new F();
    }
    
    //クローンはオブジェクトを作成する手段です.
    3.JSの原型継承
    すべてのデータは対象です.対象を得るには、インスタンスクラスではなく、オブジェクトを原型として探してクローンします.対象者は原型を覚えています.対象がある要求に応じられない場合、この要求は自分の原型に委ねられます.
    // ES6  
    class Animal {
      constructor(name) {
        this.name = name;
       }
    
      getName() {
        return this.name;
       }
    }
    class Dog extends Animal {
      constructor(name) {
        super(name);
      }
      speak() {
        return "woof";
      }
    }
    var dog = new Dog("Scamp");
    console.log(dog.getName() + ' says ' + dog.speak());
    
    4.thisの指摘問題
    //一般的ではないwithとevalを除く場合、具体的には実際の応用において、thisの指向は大体以下の4つに分類されます.を対象とする方法で呼び出します.を普通の関数として呼び出します.コンストラクタの呼び出し.Function.prototype.callまたはFuntions.prototype.appy呼び出し.
    5.call appyの用途
  • appyは2つのパラメータを受け取り、最初のパラメータは関数の中のthisオブジェクトの指向を指定し、第2のパラメータは1つの下付きセットであり、このセットは配列でも良いし、クラス行列でもいいし、このセットの要素をパラメータとして呼び出された関数に伝達します.
  • callまたはappyを使用すると、私たちが最初に導入したパラメータがnullであれば、関数内のthisはデフォルトの宿主オブジェクトを指します.ブラウザではwindow:
  • です.
    //1.   this   
    var obj1 = {
      name: 'sven'
    };
    var obj2 = {
      name: 'anne'
    };
    window.name = 'window';
    var getName = function(){
       alert ( this.name );
    };
    getName(); //   : window
    getName.call( obj1 ); //   : sven
    getName.call( obj2 ); //   : anne
    
    //                func,       func    ,func      this    window,        div,     :
    document.getElementById( 'div1' ).onclick = function(){
      alert( this.id ); //   :div1
      var func = function(){
        alert ( this.id ); //   :undefined
      }
      func();
    };
          call    func     this,      div:
    document.getElementById( 'div1' ).onclick = function(){
      var func = function(){
         alert ( this.id ); //   :div1
      }
      func.call( this );
    };
    //2. Function.prototype.bind
    //                Function.prototype.bind,         this   ,       Function.prototype.bind   ,            ,    :
    Function.prototype.bind = function( context ){
      var self = this; //      
      return function(){ //         
        return self.apply( context, arguments ); //          ,       context        this
      }
    };
    var obj = {
      name: 'sven'
    };
    var func = function(){
      alert ( this.name ); //   :sven
    }.bind( obj);
    func();
    
    6.単例設計
    var getSingle = function ( fn ) {
      var ret;
      return function () {
        return ret || ( ret = fn.apply( this, arguments ) );
      };
    };
    
    var getScript = getSingle(function(){
      return document.createElement( 'script' );
    });
    var script1 = getScript();
    var script2 = getScript();
    alert ( script1 === script2 ); //   :true
    
    7.JSがAOPを実現する(切断面向けプログラミング)
  • の主要な役割はコア業務論理モジュールとは無関係の機能を引き出すことであり、これらの業務ロジックに関係のない機能は主にログ統計、セキュリティコントロール、異常処理などを含む.これらの機能を抜き出してから、「動的に織り込む」方式で業務ロジックモジュールに組み込む.このようにする利点は、まず、業務論理モジュールの純粋さと高凝集性を維持し、次にログ統計などの機能モジュールを容易に多重化できることである.
  • Function.prototype.before = function( beforefn ){
      var __self = this; //         
      return function(){ //              "  "  
        //      ,   this     ,                                   
        beforefn.apply( this, arguments ); 
     //                  ,     this     
       return __self.apply( this, arguments );// __self === func
      }
    };
    Function.prototype.after = function( afterfn ){
      var __self = this;
      return function(){
        var ret = __self.apply( this, arguments );
        afterfn.apply( this, arguments );
        return ret;
      }
    };
    var func = function(){
      console.log( 2 );
    };
    func = func.before(function(){
      console.log( 1 );
    }).after(function(){
      console.log( 3 );
    });
    func();
    //          1      3        AOP        func   。         ,                 1、2、3。
    
    //実際の例は、ログインしてからクリックするイベントのクリック数を統計します.
    
      
    
    Function.prototype.after = function( afterfn ){
      var __self = this;
      return function(){
        var ret = __self.apply( this, arguments );
        afterfn.apply( this, arguments );
        return ret;
      }
    };
    var showLogin = function(){
      console.log( '      ' );
    }
    var log = function(){
      console.log( '     : ' + this.getAttribute( 'tag' ) );
    }
    showLogin = showLogin.after( log ); //             
    document.getElementById( 'button' ).onclick = showLogin;
      
    
    
    //実際の例では、ajax要求ごとにTokenパラメータを追加します.
    Function.prototype.before = function( beforefn ){
      var __self = this;
      return function(){
        beforefn.apply( this, arguments ); // (1)
        return __self.apply( this, arguments ); // (2)
      }
    }
    //         ,  ajax             :
    var ajax= function( type, url, param ){
      console.log(param); //   ajax       
    };
    //    Token     Function.prototyte.before    ajax      param    :
    var getToken = function(){
      return 'Token';
    }
    ajax = ajax.before(function( type, url, param ){
      param.Token = getToken();
    });
    ajax( 'get', 'http:// xxx.com/userinfo', { name: 'sven' } );
    //  ajax      log     ,Token          ajax       :
    {name: "sven", Token: "Token"}
    
    //例:プラグイン式のフォーム検証
    Function.prototype.before = function( beforefn ){
      var __self = this;
      return function(){
        if ( beforefn.apply( this, arguments ) === false ){
        // beforefn   false      return,          
          return;
        }
        return __self.apply( this, arguments );
       }
    }
    var validata = function(){
    if ( username.value === '' ){
      alert ( '       ' );
      return false;
    }
    if ( password.value === '' ){
      alert ( '      ' );
      return false;
      }
    }
    var formSubmit = function(){
    var param = {
      username: username.value,
      password: password.value
    }
    ajax( 'http:// xxx.com/login', param );
    }
    formSubmit = formSubmit.before( validata );
    submitBtn.onclick = function(){
      formSubmit();
    }
    
    //       Function.prototype.before   Function.prototype.after      ,             ,              ,         。
    
    8.JSによるコリック化実現
  • オブジェクトは、必ずしも独自の方法を使用することができますが、オブジェクトを借りることができますどのような方法がありますか?
  • var obj1 = {
      name: 'sven'
    };
    var obj2 = {
      getName: function(){
        return this.name;
      }
    };
    console.log( obj2.getName.call( obj1 ) ); //   :sven
    
    //
    //              Array.prototype    ,  call  apply        
       :
    (function(){
       Array.prototype.push.call( arguments, 4 ); // arguments   Array.prototype.push   
    console.log( arguments ); //   :[1, 2, 3, 4]
    })( 1, 2, 3 );
    
    9.関数の流れ
  • は、ユーザが自動的に出発した関数ではないものもあり、これらの場面では、関数が非常に頻繁に呼び出され、大きな性能問題を引き起こす可能性がある.window.onresize事件.mousemoveイベント上传进度
  • は、関数・ストリームの原理を実現する.時間帯を設定し、いくつかの要求を無視する.
  • コード実現
  • var throttle = function ( fn, interval ) {
      var __self = fn, //               
      timer, //    
      firstTime = true; //         
      return function () {
        var args = arguments,
        __me = this;
        if ( firstTime ) { //         ,      
           __self.apply(__me, args);
          return firstTime = false;
        }
        if ( timer ) { //        ,              
          return false;
        }
       timer = setTimeout(function () { //         
         clearTimeout(timer);
         timer = null;
          __self.apply(__me, args);
        }, interval || 500 );
      };
    };
    window.onresize = throttle(function(){
      console.log( 1 );
    }, 500 );