JavaScriptデザインモデルと開発実践読書ノート


JavaScriptデザインモデルと開発実践読書ノート
最近、破片の時間を利用してKindleで「JavaScriptデザインモデルと開発実践読書」という本を読んで、最初の2章の内容を読み始めたばかりで、プロジェクトで使えると思うメモを共有しました.
私のgithubプロジェクトは不定期に更新され、必要な学生は私のgithubに移動してソースコードを表示することができます.https://github.com/lichenbuliren/design-mode-notes
1、currying関数のコリー化
Curryingは部分評価とも呼ばれる.1つのcurryingの関数はまずいくつかのパラメータを受け入れ、これらのパラメータを受け入れた後、この関数はすぐに値を求めるのではなく、別の関数に戻り続け、さっき入力したパラメータを関数形成の閉パケットに保存します.関数が本当に値を求める必要がある場合、前に渡されたすべてのパラメータは、値を求めるために一度に使用されます.
毎月のオーバーヘッドを計算する関数を作成する必要があるとします.毎日が終わる前に、毎日いくら使ったかを記録します.
汎用currying関数:
var currying = function(fn) {
  var args = [];

  return function() {
    if (arguments.length === 0) {
      return fn.apply(this, args);
    } else {
      [].push.apply(args, arguments);
      //       ,     return        !
      return arguments.callee;
    }
  }
};

var cost = (function() {
  //         
  var money = 0;

  return function() {
    for (var i = 0, len = arguments.length; i < len; i++) {
      money += arguments[i];
    }

    return money;
  }
})();

//     currying   
//     ,      fn          
//     cost              
var cost = currying(cost);

cost(200);
cost(300);
cost(500);

//     
console.log(cost());

2、uncurrying関数
Function.prototype.uncurrying = function() {
  //    selft         Array.prototype.push;
  var self = this;

  return function() {
    // arguments: { '0': { '0': 1, length: 1 }, '1': 2 }
    var obj = Array.prototype.shift.call(arguments);
    return self.apply(obj, arguments);
  }
};

//         
Function.prototype.uncurrying = function() {
  var self = this;

  return function() {
    return Function.prototype.call.apply(self, arguments);
  }
};

var push = Array.prototype.push.uncurrying();

var obj = {
  "length": 1,
  "0": 1
};

push(obj, 2);
console.log(obj);

3、関数節流
JavaScriptの関数の多くは、関数自体の実装が不合理でない限り、パフォーマンスに関連する問題には遭遇しません.しかし、いくつかの少数の場合、関数のトリガはユーザによって直接制御されるものではない.これらのシーンでは、関数が非常に頻繁に呼び出され、パフォーマンスに大きな問題が発生する可能性があります.
関数が頻繁に呼び出されるシーン:
  • window.onresizeイベント
  • mousemoveイベント
  • アップロード進捗
  • かんすうしぼりげんり
    上記の3つのシーンでは,関数がトリガされる頻度が高すぎるという共通の問題に直面していることが分かった.
    例えばwindowでonresizeイベントで現在のブラウザウィンドウサイズを印刷するには、ウィンドウサイズをドラッグ&ドロップして変更すると、コンソールは1秒に10回行われます.実際には2回か3回しか必要ありませんこれは、500 ms以内に1回印刷されることを確認するなど、いくつかのイベント要求を時間帯別に無視する必要があります.settimeoutを利用して完了できることは明らかです.
    関数スロットル実装
    /**
     *       
     * @param  {Function} fn                
     * @param  {[type]}   interval         ,   ms
     * @return {[type]}            [description]
     */
    var throttle = function(fn, interval) {
      var _self = fn,
          timer,
          firstTime = true;
    
      console.log(_self);
    
      return function() {
        var args = arguments,
            _me = this;  //            
    
        console.log(_me);
    
        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('test');
    }, 500);

    4、時分割関数
    一部の関数は確かにユーザーがアクティブに呼び出したものですが、客観的な理由でページのパフォーマンスに深刻な影響を及ぼすことがよくあります.
    1つの例は、WebQQのQQ友達リストを作成することです.リストには通常、何百人もの友達がいます.友達がノードで表される場合、ページでこのリストをレンダリングするときに、一度にページに何百人ものノードを作成する可能性があります.
    短時間でページにDOMノードを大量に追加してもブラウザが耐えられないのは明らかで、私たちが見た結果はブラウザのカートンが偽死することも多い.この問題を解決するには時間分割関数が必要です
    /**
     *       
     *     WebQQ     
     * @param  {[type]}   data                
     * @param  {Function} fn                  
     * @param  {[type]}   count               
     * @param  {[type]}   interval       
     * @return {[type]}            [description]
     */
    var timeChunk = function(data, fn, count, interval) {
      var t;
    
      var len = data.length;
    
      var start = function() {
        for (var i = 0; i < Math.min(count || 1, data.length); i++) {
          var obj = data.shift();
          fn(obj);
        }
      }
    
      return function() {
        t = setInterval(function() {
          if (data.length === 0) {
            return clearInterval(t);
          }
    
          start();
        }, interval);
      }
    }

    5、不活性負荷関数
    イベントバインド関数の作成を例にとると、最初の条件分岐に入った後、関数内部でこの関数を書き換え、書き換えた後、私たちが必要とする関数であり、次の進入時に判断する必要はありません.
    /**
     *     
     * @param {[type]} el      [description]
     * @param {[type]} type    [description]
     * @param {[type]} handler [description]
     */
    var addEvent = function(el, type, handler) {
      if (window.addEventListener) {
        addEvent = function(el, type, handler) {
          el.addEventListener(type, handler, false);
        }
      } else if (window.attachEvent) {
        addEvent = function(el, type, handler) {
          el.attachEvent('on' + type, handler);
        }
      }
    
      addEvent(el, type, handler);
    }

    Q&A
    しばらくこのように多くて、後で不定期にいくつか私がこの本を読むことについてのノートの内容を更新します!