中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久

深入剖析JavaScript中的函數currying柯里化
來源:易賢網 閱讀:926 次 日期:2016-07-06 11:39:00
溫馨提示:易賢網小編為您整理了“深入剖析JavaScript中的函數currying柯里化”,方便廣大網友查閱!

下面小編就為大家帶來一篇深入剖析JavaScript中的函數currying柯里化。小編覺得挺不錯的,現在分享給大家,也給大家做個參考,一起跟隨小編過來看看吧

curry化來源與數學家 Haskell Curry的名字 (編程語言 Haskell也是以他的名字命名)。 

柯里化通常也稱部分求值,其含義是給函數分步傳遞參數,每次傳遞參數后部分應用參數,并返回一個更具體的函數接受剩下的參數,這中間可嵌套多層這樣的接受部分參數函數,直至返回最后結果。

因此柯里化的過程是逐步傳參,逐步縮小函數的適用范圍,逐步求解的過程。 

柯里化一個求和函數 

按照分步求值,我們看一個簡單的例子

var concat3Words = function (a, b, c) { 

  return a+b+c; 

}; 

var concat3WordsCurrying = function(a) { 

  return function (b) { 

    return function (c) { 

      return a+b+c; 

    }; 

  }; 

}; 

console.log(concat3Words("foo ","bar ","baza"));      // foo bar baza 

console.log(concat3WordsCurrying("foo "));         // [Function] 

console.log(concat3WordsCurrying("foo ")("bar ")("baza")); // foo bar baza

可以看到, concat3WordsCurrying("foo ") 是一個 Function,每次調用都返回一個新的函數,該函數接受另一個調用,然后又返回一個新的函數,直至最后返回結果,分布求解,層層遞進。(PS:這里利用了閉包的特點) 

那么現在我們更進一步,如果要求可傳遞的參數不止3個,可以傳任意多個參數,當不傳參數時輸出結果? 

首先來個普通的實現:

var add = function(items){ 

  return items.reduce(function(a,b){ 

    return a+b 

  }); 

}; 

console.log(add([1,2,3,4]));

但如果要求把每個數乘以10之后再相加,那么: 

var add = function (items,multi) { 

  return items.map(function (item) { 

    return item*multi; 

  }).reduce(function (a, b) { 

    return a + b 

  }); 

}; 

console.log(add([1, 2, 3, 4],10));

好在有 map 和 reduce 函數,假如按照這個模式,現在要把每項加1,再匯總,那么我們需要更換map中的函數。 

下面看一下柯里化實現: 

var adder = function () { 

  var _args = []; 

  return function () { 

    if (arguments.length === 0) { 

      return _args.reduce(function (a, b) { 

        return a + b; 

      }); 

    } 

    [].push.apply(_args, [].slice.call(arguments)); 

    return arguments.callee; 

  } 

};   

var sum = adder(); 

console.log(sum);   // Function 

sum(100,200)(300);  // 調用形式靈活,一次調用可輸入一個或者多個參數,并且支持鏈式調用 

sum(400); 

console.log(sum());  // 1000 (加總計算) 

上面 adder是柯里化了的函數,它返回一個新的函數,新的函數接收可分批次接受新的參數,延遲到最后一次計算。 

通用的柯里化函數

更典型的柯里化會把最后一次的計算封裝進一個函數中,再把這個函數作為參數傳入柯里化函數,這樣即清晰,又靈活。

例如 每項乘以10, 我們可以把處理函數作為參數傳入:

var currying = function (fn) { 

  var _args = []; 

  return function () { 

    if (arguments.length === 0) { 

      return fn.apply(this, _args); 

    } 

    Array.prototype.push.apply(_args, [].slice.call(arguments)); 

    return arguments.callee; 

  } 

}; 

var multi=function () { 

  var total = 0; 

  for (var i = 0, c; c = arguments[i++];) { 

    total += c; 

  } 

  return total; 

}; 

var sum = currying(multi);  

   

sum(100,200)(300); 

sum(400); 

console.log(sum());   // 1000 (空白調用時才真正計算)

這樣 sum = currying(multi),調用非常清晰,使用效果也堪稱絢麗,例如要累加多個值,可以把多個值作為做個參數 sum(1,2,3),也可以支持鏈式的調用,sum(1)(2)(3) 

柯里化的基礎

上面的代碼其實是一個高階函數(high-order function), 高階函數是指操作函數的函數,它接收一個或者多個函數作為參數,并返回一個新函數。此外,還依賴與閉包的特性,來保存中間過程中輸入的參數。即: 

函數可以作為參數傳遞 

函數能夠作為函數的返回值 

閉包 

柯里化的作用 

延遲計算。上面的例子已經比較好低說明了。

參數復用。當在多次調用同一個函數,并且傳遞的參數絕大多數是相同的,那么該函數可能是一個很好的柯里化候選。

動態創建函數。這可以是在部分計算出結果后,在此基礎上動態生成新的函數處理后面的業務,這樣省略了重復計算。或者可以通過將要傳入調用函數的參數子集,部分應用到函數中,從而動態創造出一個新函數,這個新函數保存了重復傳入的參數(以后不必每次都傳)。例如,事件瀏覽器添加事件的輔助方法: 

var addEvent = function(el, type, fn, capture) { 

  if (window.addEventListener) { 

    el.addEventListener(type, function(e) { 

      fn.call(el, e); 

    }, capture); 

  } else if (window.attachEvent) { 

    el.attachEvent("on" + type, function(e) { 

      fn.call(el, e); 

    }); 

  } 

};

每次添加事件處理都要執行一遍 if...else...,其實在一個瀏覽器中只要一次判定就可以了,把根據一次判定之后的結果動態生成新的函數,以后就不必重新計算。 

var addEvent = (function(){ 

  if (window.addEventListener) { 

    return function(el, sType, fn, capture) { 

      el.addEventListener(sType, function(e) { 

        fn.call(el, e); 

      }, (capture)); 

    }; 

  } else if (window.attachEvent) { 

    return function(el, sType, fn, capture) { 

      el.attachEvent("on" + sType, function(e) { 

        fn.call(el, e); 

      }); 

    }; 

  } 

})();

這個例子,第一次 if...else... 判斷之后,完成了部分計算,動態創建新的函數來處理后面傳入的參數,這是一個典型的柯里化。 

Function.prototype.bind 方法也是柯里化應用

與 call/apply 方法直接執行不同,bind 方法 將第一個參數設置為函數執行的上下文,其他參數依次傳遞給調用方法(函數的主體本身不執行,可以看成是延遲執行),并動態創建返回一個新的函數, 這符合柯里化特點。 

var foo = {x: 888}; 

var bar = function () { 

  console.log(this.x); 

}.bind(foo);        // 綁定 

bar();           // 888 

下面是一個 bind 函數的模擬,testBind 創建并返回新的函數,在新的函數中將真正要執行業務的函數綁定到實參傳入的上下文,延遲執行了。 

Function.prototype.testBind = function (scope) { 

  var fn = this;          //// this 指向的是調用 testBind 方法的一個函數, 

  return function () { 

    return fn.apply(scope); 

  } 

}; 

var testBindBar = bar.testBind(foo); // 綁定 foo,延遲執行 

console.log(testBindBar);       // Function (可見,bind之后返回的是一個延遲執行的新函數) 

testBindBar();            // 888 

這里要注意 prototype 中 this 的理解。

以上這篇深入剖析JavaScript中的函數currying 柯里化就是小編分享給大家的全部內容了,希望能給大家一個參考

更多信息請查看網絡編程
由于各方面情況的不斷調整與變化,易賢網提供的所有考試信息和咨詢回復僅供參考,敬請考生以權威部門公布的正式信息和咨詢為準!

2026上岸·考公考編培訓報班

  • 報班類型
  • 姓名
  • 手機號
  • 驗證碼
關于我們 | 聯系我們 | 人才招聘 | 網站聲明 | 網站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點 | 投訴建議
工業和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網安備53010202001879號 人力資源服務許可證:(云)人服證字(2023)第0102001523號
云南網警備案專用圖標
聯系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關注公眾號:hfpxwx
咨詢QQ:1093837350(9:00—18:00)版權所有:易賢網
云南網警報警專用圖標
中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久
亚洲美洲欧洲综合国产一区| 亚洲欧美日产图| 国产一区白浆| 亚洲另类在线一区| 日韩午夜剧场| 亚洲一区二区久久| 欧美不卡三区| 国产精品推荐精品| 亚洲精品久久嫩草网站秘色 | 国产亚洲一区在线播放| 欧美日韩在线免费视频| 欧美日韩调教| 伊人夜夜躁av伊人久久| 尤妮丝一区二区裸体视频| 亚洲视屏在线播放| 老鸭窝毛片一区二区三区| 欧美日韩国产成人| 国产综合视频| 亚洲免费中文| 欧美三日本三级少妇三2023 | 亚洲一区二区三区国产| 亚洲欧美国产三级| 久久精品一本| 国产日韩欧美亚洲一区| 欧美亚洲专区| 国产一区二区三区久久久久久久久| 99国内精品久久| 欧美日韩国产精品自在自线| 亚洲精品精选| 在线免费一区三区| 亚洲欧美精品| 国内精品久久久| 久久riav二区三区| 亚洲国产福利在线| 欧美日韩视频专区在线播放 | 亚洲成人在线观看视频| 久久精品免费| 99天天综合性| 国产日产高清欧美一区二区三区| 欧美主播一区二区三区| 亚洲国产黄色片| 欧美午夜无遮挡| 久久―日本道色综合久久| 欧美www视频| 欧美日韩免费高清| 亚洲欧美日韩中文播放| 国产一区二区精品| 欧美日韩高清在线一区| 欧美在线日韩精品| 一本在线高清不卡dvd| 狠狠狠色丁香婷婷综合久久五月| 欧美精品免费播放| 久久青草久久| 久久偷看各类wc女厕嘘嘘偷窃| 亚洲激情视频在线| 国产毛片精品国产一区二区三区| 欧美激情综合色综合啪啪| 久久精品国产亚洲精品| 午夜精品av| 欧美亚洲综合久久| 久久aⅴ国产欧美74aaa| 亚洲网站啪啪| 香蕉乱码成人久久天堂爱免费| 一区二区三区成人精品| 在线视频日韩| 亚洲欧美日产图| 久久久91精品国产| 久久综合九色综合网站| 欧美a级片一区| 欧美日韩国产一级| 国产精品捆绑调教| 国产在线乱码一区二区三区| 国产一区91| 亚洲欧美日韩视频一区| 欧美在线黄色| 欧美日韩国产专区| 欧美午夜精品一区二区三区| 国产精品毛片a∨一区二区三区| 国产精品美女久久久免费| 国产精品免费小视频| 狠狠久久婷婷| 99国产精品久久久久久久久久| 亚洲欧洲av一区二区| 玖玖国产精品视频| 国产精品99免费看 | 欧美精品导航| 国产精品theporn| 国产一区二区剧情av在线| 亚洲精品在线观看免费| 久久av资源网站| 国产精品久久久久久久久久免费| 在线免费观看视频一区| 亚洲视频专区在线| 欧美精品一区二区三区高清aⅴ| 国产日产欧产精品推荐色| 日韩午夜av| 欧美日韩中文在线| 国产精品萝li| 日韩视频免费观看高清完整版| 亚洲影院一区| 欧美另类99xxxxx| 亚洲电影自拍| 麻豆成人精品| 在线观看欧美日韩| 欧美一区国产一区| 国产精品嫩草99av在线| 亚洲特级毛片| 国产精品视频男人的天堂| 国产精品99久久久久久久久久久久 | 国产精品伊人日日| 亚洲一区二区伦理| 欧美午夜大胆人体| 久久成人羞羞网站| 国产一区在线观看视频| 久久一日本道色综合久久| 在线观看国产精品淫| 欧美日韩日本网| 久久成人人人人精品欧| 国模套图日韩精品一区二区| 欧美亚洲一区在线| 亚洲国产精品一区二区三区| 久久综合色播五月| 一本一本a久久| 国外视频精品毛片| 欧美日韩精品是欧美日韩精品| 午夜精品一区二区三区在线| 狠狠v欧美v日韩v亚洲ⅴ| 久久久蜜桃一区二区人| 亚洲精品老司机| 国产精品三级久久久久久电影| 久久av一区二区三区亚洲| 91久久精品日日躁夜夜躁国产| 国产精品久久久久天堂| 麻豆freexxxx性91精品| 性欧美18~19sex高清播放| 性欧美xxxx大乳国产app| 亚洲日本成人网| 国产日韩亚洲欧美综合| 欧美激情女人20p| 久久亚洲国产精品一区二区| 亚洲视频中文字幕| 999亚洲国产精| 亚洲国产精品高清久久久| 国产真实精品久久二三区| 国产综合久久久久久鬼色| 欧美精品在线看| 欧美二区在线观看| 久久这里只有| 男人的天堂成人在线| 蜜乳av另类精品一区二区| 久久免费偷拍视频| 美国十次成人| 麻豆成人在线| 欧美日本不卡| 国产精品福利在线| 国产免费观看久久| 亚洲成人在线视频网站| 亚洲第一页中文字幕| 黄色av日韩| 亚洲精品久久久久久下一站 | 欧美午夜不卡在线观看免费| 欧美日韩成人一区二区三区| 欧美日韩视频在线观看一区二区三区| 欧美日韩国产综合网| 国产美女精品| 日韩视频在线一区二区| 亚洲午夜国产成人av电影男同| 午夜亚洲福利| 久久亚洲私人国产精品va媚药| 久久久精品欧美丰满| 蘑菇福利视频一区播放| 欧美日本在线视频| 国产专区精品视频| 亚洲精品久久久蜜桃| 亚洲欧美日韩国产一区二区三区| 久久精品视频网| 国产精品久久999| 亚洲人在线视频| 久久精品国产99| 欧美午夜不卡| 99精品欧美一区二区三区| 免费不卡在线观看| 国产一区在线看| 欧美一区永久视频免费观看| 欧美激情视频给我| 亚洲国产日韩综合一区| 欧美主播一区二区三区美女 久久精品人 | 亚洲三级影院| 老司机亚洲精品| 亚洲国产精品成人va在线观看| 亚洲男人的天堂在线aⅴ视频| 欧美体内谢she精2性欧美| 亚洲久久在线| 欧美日韩亚洲一区二区三区四区 | 亚洲人成网站色ww在线| 欧美电影免费观看| 亚洲破处大片| 欧美精品黄色| 亚洲香蕉网站| 国产日韩免费|