含义
把接收多个参数的函数变换成接收一个单一参数(最初函数的第一个参数)的函数,并返回接受剩余的参数而且返回结果的新函数的技术。 柯里化又称部分求值,字面意思就是不会立刻求值,而是到了需要的时候再去求值。
作用
缓存参数调用后的函数
function volume (l, w, h) {
return l * w * h
}
// 碰巧你仓库里的所有物品都是100m高。你会看到你不停地用h=100来调用这个函数:
volume(200, 30, 100) // 2003000
volume(32, 45, 100) // 144000
volume(2322, 232, 100) // 53870400
// 为了解决这个问题,你把volume函数柯里化(像我们之前做过的):
function volume (h) {
return (w) => {
return (l) => {
return l * w * h
}
}
}
// 我们能给同类物品定义一个特殊函数:
const hCylinderHeight = volume(100)
hCylinderHeight(200)(30) // 600000
hCylinderHeight(2322)(232) // 53870400
代码实现
只能接受一个参数的柯里化
function curry_one(fn) {
if (fn.length <= 1) return fn;
// 这是我一开始的实现
// 后来发现 rest 是多余的,下面这样就行了,fn.length 多处用到,可以提出来
// const generator = (args) => (args.length === fn.length ? fn(...args) : arg => generator([...args, arg]));
const generator = (args, rest) => (
rest == 0 ?
fn(...args) :
arg => generator([...args, arg], rest - 1)
);
return generator([], fn.length);
};
可以接受多个参数的柯里化
function curry_multi(fn) {
const generator = (...args) => {
return
(args.length === fn.length) ?
fn(...args) :
(..._args) => generator(...args, ..._args)
}
return generator;
}
const sum = (a, b, generator) => a + b + generator;
const curriedSum = curry_one(sum);
const res = curriedSum(1)(2)(3)
console.log(res); // 6
const log = (a, b, generator) => {
console.log(a, b, generator);
};
const curriedLog = curry2(log);
curriedLog('a')('b')('generator'); // a b generator
自己实现的
/**
* 返回一个函数,
* 当该函数接受到的参数和为柯里化函数的参数总数时,触发柯里化函数,
* 否则用闭包的试试保留柯里化的参数
* @param {*} callback 需要柯里化的函数
*/
function cury(callback){
let len = callback.length;
let saveArg = [];
function fn(...arg){
saveArg = saveArg.concat(arg);
if(saveArg.length === len) {
return callback(...saveArg);
}
else {
return fn;
}
}
return fn;
}
function add(a,b,c,d) {
console.log(a,b,c,d);
}
let test = cury(add);
test(1)(2)(2)(4)