函数克里化,是指 多个参数 的函数转换成只接受 单一参数 的函数,且返回计算完成后的结果。
下面我们举个例子,
// 普通函数
function add(x, y) {
return x + y
}
// 递归函数
function curryingAdd(x) {
return function (y) {
return x + y
}
}
add(1, 2) // 3
curryingAdd(1)(2) // 3,
无论是add()函数还是curryingAdd()函数,这都是特定的传参格式。
// 普通函数
function add(x, y, z) {
return x + y + z
}
// 递归函数(注意)
function curryingAdd(x) {
return function (y) {
return function (z) {
return x + y + z
}
}
}
add(1, 2, 3) // 3
curryingAdd(1)(2)(3) // 3,
如果不单单只是1和2,而是更多,总不能一个个加下去或者一次次递归下去。
而克里化就是将这种类似多个参数的函数转换成只接受一个单一参数的函数。
实现思想
1、实现add(1)(2)(3)
function add(x) {
var currying = function (y) {
x = x + y;
console.log('x', x)
return currying;
};
currying.toString = function () {
return x;
};
return currying;
}
add(1)(2)(3) // 6
采用递归进行计算,利用toString隐式转换的特性,当最后执行时进行隐式转换。
2、实现add(1, 2, 3)与add(1, 2)(3)
function add() {
var args = Array.prototype.slice.call(arguments);
var currying = function() {
args.push(...arguments);
return currying;
};
currying.toString = function () {
return args.reduce(function (a, b) {
return a + b;
});
}
return currying;
}
add(1)(2)(3) // 6
add(1, 2)(3)(4) // 10
const ret = add(1)(2)(3)(4)(5) // 15
console.log(ret.toString());
声明函数,使用闭包特性定义一个数组,来缓存所有的参数;
多次()只是在重复调用闭包函数,当所有的()执行完后;
此时开始进行隐式转换(利用toString隐式转换的特性);
最后将计算值返回出来。