什么是函数柯里化?
函数柯里化主要用于给函数分步传递参数,每次传递参数进行处理,并返回一个更具体的函数来接受剩下的参数,这中间可以嵌套多层,直至返回最后的结果。
实现思路
- 接收一个处理数据的函数。
- 定义一个数组用于接收所有的参数。
- 返回一个函数,如果返回的函数接收的参数的长度是0,则返回fn执行的结果,如果不是0,则将参数push进数组中,并返回函数。
面试回答版
// 柯里化函数
const curry = (func) => {
return function curryFunc(...args) {
// 实参 < 形参, 返回一个函数,并等待接受剩余参数
if (args.length < func.length) {
return function () {
// 合并每次调用函数时传递的参数
return curryFunc(...[...args, ...Array.from(arguments)]);
};
}
// 当实参 >= 形参时,直接执行函数返回结果
return func(...args);
};
};
function test(n1, n2, n3) {
return n1 + n2 + n3;
}
const result = curry(test);
console.log('sum', result(1)(2)(3)); // 6
console.log('sum', result(1, 2)(1)); // 4
console.log('sum', result(1)(2)(1)); // 4
console.log('sum', result(1, 2, 1)); // 4
代码实现一(需要额外调用)
// 手写函数柯里化
const curring = function(fn) {
const args = [];
return function result(...rest) {
if (rest.length === 0) {
return fn(...args)
} else {
args.push(...rest);
return result;
}
}
}
const sum = (...arg) => {
return arg.reduce((pre,cur) => {
return pre + cur
},0)
}
curring(sum)(1)(2,5)(3)()
代码实现二(不需要额外调用)
// 手写函数科里化
// foo(1)(2)(3)
const sum = (arg) => {
return arg.reduce((pre,cur) => {
return pre + cur;
},0)
};
const foo = (...args1) => {
const sum1 = sum(args1);
const fn = (...args2) => {
const sum2 = sum(args2);
return foo(sum1 + sum2);
}
fn.toString = () => {
return sum1;
}
return fn;
}
// 这种方式只能使用== 不能使用===
foo(1)(2)(3) == 6
但是这种方式只能使用==,不能使用===
代码实现三:sumOf版
/**
* 实现一个累加器
* add(1,2)(3).sumOf()
* add(1)(2,3).sumOf()
* add(1)(2)(3).sumOf()
* add(1,2,3).sumOf()
*/
function Add() {
if (!Add.nums) {
Add.nums = [];
}
Add.nums.push(...arguments);
return Add;
}
Add.sumOf = () => {
return Add.nums.reduce((a, b) => a + b);
}
console.log(Add(1,2)(3).sumOf());