柯里化
什么是柯里化?
f(x)和g(x)合成為f(g(x)),有一個隱藏的前提,就是f和g都只能接受一個參數(shù),如果可以接收多個參數(shù),比如 f(x, y) 和 g(a, b, c),函數(shù)合成就非常麻煩了。
這時就需要使用到函數(shù)柯里化了,所謂的“柯里化”,就是把一個多參數(shù)的函數(shù),轉(zhuǎn)化為單參數(shù)函數(shù)。如下:
// 柯里化之前
function add(x, y) {
return x + y;
}
add(1, 2) // 3
// 柯里化之后
function addX(y) {
return function (x) {
return x + y;
};
}
addX(2)(1) // 3
有了柯里化之后, 我們就能夠做到,所有函數(shù)都只接受一個參數(shù)。
函數(shù)柯里化又稱為部分求值,就是不會立即求值,而是等到了需要的時候再去求值。
有這樣的一個場景,記錄程序員一個月的加班總時間,那么好,我們首先要做的就是記錄程序員每天加班的時間,然后把一個月中每天加班的時間相加,這樣,就得到了一個月的加班總時間。
問題來了,我們又很多方法來實(shí)現(xiàn),比如最簡單的:
var monthTime = 0;
function overtime(time) {
return monthTime += time;
}
overtime(3.5); // 第一天
overtime(4.5); // 第二天
overtime(2.2); // 第三天
//...
//
//
//
overtime(3.2); // 第三十天
console.log(monthTime);
這個思路應(yīng)該是最簡單的,就是一個函數(shù),變量時monthTime,每天加上加班小時數(shù)之后返回總的加班時間。
每次傳入加班時間都進(jìn)行累加,這樣當(dāng)然沒問題,但你知道,如果數(shù)據(jù)量很大的情況下,這樣會大大犧牲性能。
那怎么辦?這就是柯里化要解決的問題。
其實(shí)我們不必每天都計(jì)算加班時間,只需要保存好每天的加班時間,在月底時計(jì)算這個月總共的加班時間,所以,其實(shí)只需要在月底計(jì)算一次就行。
即對于每次輸入的時間,我們只需要保存起來即可,這樣,沒有了加法返回的步驟,就可以減少運(yùn)算了。
如下所示的overtime函數(shù)還不是一個柯里化函數(shù)的完整實(shí)現(xiàn),但是可以幫助我們了解其中的核心思想了:
這里的思想非常簡單, 就是如果傳入了參數(shù),那么就把這個參數(shù)push到args數(shù)組中,表明這是在累加的階段; 如果沒有傳入?yún)?shù),那么就說明已經(jīng)加完了,只要最后一次求和即可。 關(guān)鍵是這個overtime函數(shù)返回的是一個函數(shù)。 這里需要注意。如下:
var overtime = (function () {
var days = [];
return function () {
if (arguments.length == 1) {
[].push.apply(days, arguments);
} else {
var total = 0;
for (var i = 0; i < days.length; i++) {
total += days[i];
}
console.log(total);
return total;
}
}
})();
overtime(1);
overtime(2);
overtime(3);
overtime(4);
overtime(); // 10
即對于前面的四個overtime函數(shù)被調(diào)用的時候,其實(shí)只是保存了變量而已,并沒有求值,直到最后才一起求值,這樣有利于提高效率。
https://rockjins.js.org/2017/02/15/2017-02-15-curring-uncurring/
總結(jié)
- 上一篇: 端口基础知识
- 下一篇: 为什么mysql 5.7.24启停不显示