標籤:利用 span for 轉化 div style cal ret 遍曆
內容來自曾探,《JavaScript設計模式與開發實踐》,P49
函數柯裡化(function currying)又稱部分求值。一個currying的函數首先會接受一些參數,接受了這些參數後,該函數並不會立即求值,而是繼續返回另外一個函數,剛才傳入的參數在函數形成的閉包裡被儲存起來。待到函數真正需要求值的時候,之前傳入的參數都會被一次性用於求值。
假設我們要編寫一個計算每月開銷的函數。在每天結束之前,我們都要記錄今天花了多少錢,代碼如下:
var monthlyCost = 0;var cost = function(money){ monthlyCost += money;};cost(100);//第一天開銷cost(200);//第二天開銷cost(300);//第三天開銷//cost(700);//第三十天開銷alert(monthlyCost);//輸出:600
這段代碼在每天結束後都會記錄並計算到今天為止花了多少錢,但我們不太關心每天花掉多少,只想知道月底總共花掉了多少,也就是說,只需要在月底計算一次。
如果在每個月的前二十九天,我們都只是儲存好當天的開銷,直到第30天才進行求值計算,這就達到了我們的目的。下面的代碼還不是一個currying函數的完整實現,但有助於我們瞭解其思想:
var cost = (function(){ var args = []; return function(){ if(arguments.length === 0){ var money = 0; for(var i = 0, l = args.length; i < l; i++){ money += args[i]; } return money; }else{ [].push.apply(args, arguments); } }}());cost(100);//未真正求值cost(200);//未真正求值cost(300);//未真正求值console.log(cost());//求值並輸出:600
接下來編寫一個通用的function 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 arguments.callee; } }};
var cost = (function(){ var money = 0; return function(){ for(var i = 0, l = arguments.length; i < l; i++){ money += arguments[i]; } return money; }}());var cost = currying(cost);//轉化為currying函數cost(100);//未真正求值cost(200);//未真正求值cost(300);//未真正求值console.log(cost());//求值並輸出:600
至此,我們完成了一個currying函數的編寫,當調用cost()時,如果明確帶上參數,表明此時並不進行真正的求值計算,而是把這些參數儲存起來,此時讓cost()函數返回另外一個函數。只有當我們以不帶參數的形式執行cost()時,才利用前面儲存的所有參數,真正開始求值計算。
內容來自曾探,《JavaScript設計模式與開發實踐》,P49
js-函數柯裡化