今天接觸到了一個以前沒據說過的東東,感受很好玩~分享給你們~爲了完全的瞭解一下相關概念,特地拜讀了一下張鑫旭大神的相關文章連接以下~:數組
http://www.zhangxinxu.com/wor...
感謝大神分享,本文將截取大神分享的部分及加上本身的小小理解~
先發一波定義~(源自百度百科)瀏覽器
在計算機科學中,柯里化(Currying)是把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,而且返回接受餘下的參數且返回結果的新函數的技術。這個技術由 Christopher Strachey 以邏輯學家 Haskell Curry 命名的,儘管它是 Moses Schnfinkel 和 Gottlob Frege 發明的。
大神用於函數柯里化用的比喻至關的形象很是有助於理解~
「柯里化」就像某些官員的把戲,官員要弄7個老婆,礙於國策(一夫一妻)以及年老弟衰,表面上就1個老婆,實際上剩下的6個暗地裏消化,代碼表示以下:app
var curring = function(fn){ // fn 指官員消化老婆的手段 var args = [].slice.call(arguments,1); // 截取arguments中的第一個生成一個數組,也就是當前語境下的明面上的合法老婆 return function(){ // 將已有的參數和新傳進來的參數合併爲一個數組,對應已有的合法老婆和新搞定的老婆 var newArgs = args.concat([].slice.call(arguments)); // 將全部的參數newArgs綁定給fn~ return fn.apply(null,newArgs); } } // 下面爲官員如何搞定7個老婆作測試 // 得到合法老婆 var getWife = currying(function(){ var allWife = [].slice.call(arguments); console.log(allWife.join(';')) },"合法老婆"); // 得到其餘6個老婆 getWife("小老婆1","小老婆2","小老婆3","小老婆4","小老婆5","小老婆6"); // 換一批老婆 getWife("大老婆","小老婆","俏老婆","刁蠻老婆","乖老婆","送上門老婆"); // 再換一批老婆 getWife("超越韋小寶的老婆");
效果是這樣的~
wordpress
不管輸入多少個參數,都會打印輸出,且都會帶着第一個參數~
上文代碼fn.apply(null,newArgs)
中的null
本是應該制定fn中this的指向的對象,沒有因此就用null啦,算是一個小技巧~函數
理解理解以後再想一想,這個東西有什麼用啊~~
柯里化有三個常見的應用:測試
這裏舉個很實用的例子,兼容現代瀏覽器以及IE瀏覽器的事件添加方法:this
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); }); } };
上面的方法有什麼問題呢?很顯然,咱們每次使用addEvent爲元素添加事件的時候,(eg. IE6/IE7)都會走一遍if...else if ...,其實只要一次斷定就能夠了,怎麼作?–柯里化。改成下面這樣子的代碼:spa
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); }); }; } })();
初始addEvent的執行其實只實現了部分的應用(只有一次的if...else if...斷定),而剩餘的參數應用都是其返回函數實現的,典型的柯里化。code
var curryWeight = function(fn) { var _weight = []; return function() { if (arguments.length === 0) { return fn.apply(null, _weight); } else { _weight = _weight.concat([].slice.call(arguments)); } } }; var weight = 0; var addWeight = curryWeight(function() { var i=0; len = arguments.length; for (i; i<len; i+=1) { weight += arguments[i]; } }); addWeight(2.3); addWeight(6.5); addWeight(1.2); addWeight(2.5); addWeight(); // 這裏才計算 console.log(weight); // 12.5
先傳入參數,直到調用的時候才執行計算~對象
今天的分享就先到這裏了~願與各位共勉~