柯里化
js
function curry(fn, args) {
var length = fn.length;
var args = args || [];
return function () {
newArgs = args.concat(Array.prototype.slice.call(arguments));
console.log(newArgs);
if (newArgs.length < length) {
return curry.call(this, fn, newArgs);
} else {
return fn.apply(this, newArgs);
}
};
}
function multiFn(a, b, c) {
return a * b * c;
}
var multi = curry(multiFn);
multi(2)(3)(4);
multi(2, 3, 4);
multi(2)(3, 4);
multi(2, 3)(4);
ES6 写法
js
const curry =
(fn, arr = []) =>
(...args) =>
(arg) =>
arg.length === fn.length ? fn(...arg) : curry(fn, arg)([...arr, ...args]);
let curryTest = curry((a, b, c, d) => a + b + c + d);
curryTest(1, 2, 3)(4); //返回10
curryTest(1, 2)(4)(3); //返回10
curryTest(1, 2)(3, 4); //返回10
柯里化加闭包
js
// 实现一个add方法, 使计算结果能够满足以下预期
add(1)(2)(3) = 6
add(1,2,3)(4) = 10
add(1)(2)(3)(4)(5) = 15
js
function add(...args) {
// 累加当前的参数
let sum = args.reduce((acc, cur) => acc + cur, 0);
// 返回一个函数,用于后续调用
function innerAdd(...innerArgs) {
// 累加新的参数
sum += innerArgs.reduce((acc, cur) => acc + cur, 0);
// 返回自身,使得可以继续调用
return innerAdd;
}
// 重写 innerAdd 的 toString 方法,以便在需要时返回结果
innerAdd.toString = function() {
return sum;
};
// 或者重写 innerAdd 的 valueOf 方法
innerAdd.valueOf = function() {
return sum;
};
return innerAdd;
}
// 使用示例
console.log(add(1)(2)(3).toString()); // 6
console.log(add(1, 2, 3)(4).toString()); // 10
console.log(add(1)(2)(3)(4)(5).toString()); // 15