函數(shù)柯理化的表現(xiàn)是:把一個(gè)需要傳入多個(gè)變量的函數(shù)變?yōu)槎鄠€(gè)嵌套函數(shù)建峭,并且內(nèi)層函數(shù)會(huì)調(diào)用上層函數(shù)的變量。
現(xiàn)在有一個(gè)簡(jiǎn)單的add
函數(shù):
function add(x, y) {
return x + y;
}
console.log(add(1, 2)); // 3
將其改為柯理化函數(shù)
function add2(x) {
return function (y) {
return x + y;
}
}
console.log(add2(1)(2)); // 3
從上面的例子可以看出决摧,柯理化很像現(xiàn)在流行的組件化開(kāi)發(fā)模式亿蒸,將多個(gè)函數(shù)模塊組合起來(lái)凑兰,得到一個(gè)新的函數(shù)。
柯理化函數(shù)的核心是閉包边锁,因?yàn)殚]包姑食,所以內(nèi)層函數(shù)才能夠保留父作用域中的變量。
通用柯理化函數(shù)
1. 版本一
創(chuàng)建一個(gè)通用的柯理化函數(shù)的方式如下:
function currying(fun) {
var args = Array.prototype.slice.call(arguments, 1);
return function () {
var _args = args.concat(Array.prototype.slice.call(arguments));
return fun.apply(null, _args);
}
}
可以看到砚蓬,currying
函數(shù)將除了第一個(gè)fn變量矢门,將其他參數(shù)變量都賦值在args
變量中,然后將其合并在返回函數(shù)的變量參數(shù)中灰蛙,給返回函數(shù)使用。
現(xiàn)在隔躲,利用currying
改造一個(gè)支持多個(gè)入?yún)⒌?code>add函數(shù)(采用ES6語(yǔ)法):
// 支持多個(gè)入?yún)?function add(...vals) {
return vals.reduce((pre, val) => {
return pre + val;
});
}
var newAdd = currying(add, 1, 2, 3);
console.log(newAdd(4, 5, 6)); // 21
這種方式創(chuàng)建的柯理化函數(shù)只能調(diào)用一次摩梧。
2. 版本二
再實(shí)現(xiàn)一種柯理化工廠函數(shù),可以多次調(diào)用宣旱,最后統(tǒng)一求值仅父。
function currying(fn) {
var args = Array.prototype.slice.call(arguments, 1);
return function () {
if (arguments.length === 0) {
return fn.apply(this, args);
}
else {
Array.prototype.push.apply(args, arguments);
return arguments.callee;
}
}
}
利用上面的currying
改造add
函數(shù):
function add() {
var vals = Array.prototype.slice.call(arguments);
return vals.reduce((pre, val) => {
return pre + val;
});
}
var newAdd = currying(add, 1, 2, 3);
newAdd(4, 5);
newAdd(6, 7);
console.log(newAdd()); // 28
這種方式,把每次函數(shù)調(diào)用的參數(shù)都存儲(chǔ)起來(lái)浑吟,如果已無(wú)參形式調(diào)用笙纤,說(shuō)明記錄結(jié)束,需要做最終計(jì)算组力。
小結(jié)
總之省容,柯理化就是利用模塊化思想處理多參函數(shù),通過(guò)組合函數(shù)減少每個(gè)函數(shù)的入?yún)?shù)量燎字,從而提高代碼的可閱讀性及可維護(hù)性腥椒。