Javascriptg高級函數

Javascript高級函數

  • 惰性載入函數
  • 函數柯里化
  • 級聯函數

這並不全面,只是幾個主要的。html

惰性載入函數

  惰性載入表示函數執行的分支只會在函數第一次掉用的時候執行,在第一次調用過程當中,該函數會被覆蓋爲另外一個按照合適方式執行的函數,這樣任何對原函數的調用就不用再通過執行的分支了。數組

  寫一個函數用來建立XmlHttpRequest對象,瀏覽器兼容性緣由,寫出的代碼經過大量if判斷或者try,catch語句將函數引導到正確代碼處。瀏覽器

代碼示例:app

function createXHR(){
    var xhr = null;
    try {
        // Firefox, Opera 8.0+, Safari,IE7+
        xhr = new XMLHttpRequest();
    }
    catch (e) {
        // Internet Explorer 
        try {
            xhr = new ActiveXObject("Msxml2.XMLHTTP");
        }
        catch (e) {
            try {
                xhr = new ActiveXObject("Microsoft.XMLHTTP");
            }
            catch (e) {
                xhr = null;
            }
        }
    }
    return xhr;
} 

  每次調用這個函數的時候,都要先進行瀏覽器能力檢查,首先檢查瀏覽器是否支持內置的XMLHyypRequest對象,若是不支持而後檢查各版本基於ActiveX的XMLHttpRequest,每次調用該函數都是這樣,其實當第一次執行完後,若是瀏覽器支持某個特定XMLHttpRequest對象,那麼下次執行的時候這種支持性並不會改變,不必再進行一邊檢測,即便只有一個if語句,執行也確定比沒有要慢,若是咱們可讓if語句沒必要每次執行,那麼就能夠在頻繁調用的狀況下提升執行速度。而且若是在屢次createXHR後沒有處理好,還會很是容易形成內存泄漏。解決方案就是惰性載入。在已經判斷出當前瀏覽器是什麼的時候,就讓createXHR == XHR; 函數

function createXHR(){
  var xhr=null;
  if(typeof XMLHttpRequest !='undefined'){   xhr = new XMLHttpRequest(); createXHR=function(){   return new XMLHttpRequest(); } }else{   try {   xhr = new ActiveXObject("Msxml2.XMLHTTP"); createXHR=function(){   return new ActiveXObject("Msxml2.XMLHTTP"); } } catch (e) {   try {   xhr = new ActiveXObject("Microsoft.XMLHTTP"); createXHR=function(){   return new ActiveXObject("Microsoft.XMLHTTP"); } } catch (e) {   createXHR=function(){ return null; } } } } return xhr; }

  在這個惰性載入的createXHR中第一次執行的時候每一個分支都會爲createXHR從新賦值,覆蓋原函數,返回xhr對象,而第二次執行的時候就會直接調用重寫後的函數,這樣就沒必要執行每一個分支從新作檢測了。this

函數柯里化

  在計算機科學中,柯里化(英語:Currying),又譯爲卡瑞化或加里化,是把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,而且返回接受餘下的參數並且返回結果的新函數的技術。spa

  提及函數柯里化,我理解起來確實費了很大一波力,首先對於代碼中的不少部分都不理解,好比slice、call()、apply()。理解了這些以後天然可以看懂柯里化的通用實現:prototype

代碼示例:code

function currying(fn) {
    var args = Array.prototype.slice.call(arguments, 1);
    return function () {
        var innerArgs = Array.prototype.slice.call(arguments);
        var finalArgs = args.concat(innerArgs);
        console.log (finalArgs);
        return fn.apply(this,finalArgs);
    };
}
    1. 提升適用性

      代碼示例:xml

      function square(i) {
          return i * i;
      }
      
      function dubble(i) {
          return i *= 2;
      }
      
      function map(handeler, list) {
          return list.map(handeler);
      }
      
      // 數組的每一項平方
      map(square, [1, 2, 3, 4, 5]);
      map(square, [6, 7, 8, 9, 10]);
      map(square, [10, 20, 30, 40, 50]);
      // ......
      
      // 數組的每一項加倍
      map(dubble, [1, 2, 3, 4, 5]);
      map(dubble, [6, 7, 8, 9, 10]);
      map(dubble, [10, 20, 30, 40, 50]);
      

      例子中,建立了一個map通用函數,用於適應不一樣的應用場景。。同時,例子中重複傳入了相同的處理函數:square和dubble。

      應用中這種須要處理的東西會更多。通用性的加強必然帶來適用性的減弱。可是,咱們依然能夠在中間找到一種平衡。

      看下面,咱們利用柯里化改造一下:

      代碼示例:

      function square(i) {
          return i * i;
      }
      
      function dubble(i) {
          return i *= 2;
      }
      
      function map(handeler, list) {
          return list.map(handeler);
      }
      
      var mapSQ = currying(map, square);
      mapSQ([1, 2, 3, 4, 5]);
      mapSQ([6, 7, 8, 9, 10]);
      mapSQ([10, 20, 30, 40, 50]);
      // ......
      
      var mapDB = currying(map, dubble);
      mapDB([1, 2, 3, 4, 5]);
      mapDB([6, 7, 8, 9, 10]);
      mapDB([10, 20, 30, 40, 50]);
      // ......
      

      柯里化下降通用性,提升適用性。  

    2. 延遲執行

      不斷的柯里化,累計傳入的參數,最後執行。

      代碼示例:

      var add = function() {
          var _this = this,
          _args = arguments
          return function() {
              if (!arguments.length) {
                  var sum = 0;
                  for (var i = 0,c; c = _args[i++];) sum += c;
                  return sum;
              } else {
                  Array.prototype.push.apply(_args, arguments) 
      return arguments.callee; } } } add(1)(2)(3)(4)();//10

      柯里化:

      var curry = function(fn) {
          var _args = []
          return function cb() {
              if (arguments.length == 0) {
                  return fn.apply(this, _args)
              }
              Array.prototype.push.apply(_args, arguments);
              return cb;
          }
      }
      

        

    3. 固定易變因素

      柯里化特性決定了它能夠提早把易變因素,傳參固定下來,生成一個更明確的應用函數。最典型的表明應用,是bind函數用以固定this這個易變對象。

      Function.prototype.bind = function(context) {
          var _this = this,
          _args = Array.prototype.slice.call(arguments, 1);
          return function() {
              return _this.apply(context, _args.concat(Array.prototype.slice.call(arguments)))
          }
      }
      

但其實我仍是沒有那麼透徹的理解函數柯里化,應該等到其餘的知識掌握的更加熟練,理解起來也纔會更加容易吧

級聯函數

  級聯函數也叫鏈式函數,方法鏈通常適合對一個對象進行連續操做(集中在一句代碼),必定程度上把相關的屬性都連到一塊兒,減小代碼量,缺點是它佔用了函數的返回值。

function myclassA(){
 this.name="";
 this.age="";
 this.sex="";
}
myclassA.prototype={
 setname:function(){
  this.name="katherine";
  return this;
 },
 setage:function(){
  this.age="22";
  return this;
 },
 setsex:function(){
  this.sex='girl';
  return this;
 }
}
var me =new myclassA();
console.log(me.setname().setage().setsex());

// myclassA {name: "katherine", age: "22", sex: "girl"}

  這一篇整整弄了兩天才弄完,可是仍是有些搞不懂函數柯里化,我想只能在往後的開發中,慢慢接觸項目來解鎖理解了【攤手】

相關文章
相關標籤/搜索