概念:
将多个参数的函数转化为一个参数且返回一个新函数的技术
分析:
(1) 多个参数=>1个参数
(2) 返回一个新函数
代码:
function curry(fn, args) {
var slice = Array.prototype.slice; // 缓存数组的 slice 方法
var length = fn.length; // 函数参数的长度
var args = args || []; // 闭包保存参数列表
return function() {
var _args = slice.call(arguments); // 获取参数列表
var newArgs = args.concat(_args); // 新的参数与上一次的参数拼接起来
if(newArgs.length < length) {
/**如果传入的参数列表长度还没有超过函数定义时的参数长度,迭代 curry 函数
* 自己调用自己,将保存的参数传递到下一个柯里化函数
* */
return curry.call(this, fn, newArgs);
} else {
/**如果传入的参数列表长度已经超过函数定义时的参数长度,就执行。
*/
return fn.apply(this, newArgs);
}
}
}
function multiFn(a, b, c, d) {
return a * b * c * d;
}
var multi = curry(multiFn);
var result = multi(2)(3)(4)(5);
console.log('result :>> ', result);
核心思路:
function curry(fn, ...args) {
...
return function(...args2) {
var newArgs = [...args, ...args2];
if(fn.length > newArgs.length) {
return curry.call(this, fn, newArgs)
} else {
return fn.call(this, newArgs)
}
}
}
练习:
/**
* 实现 addFn(1)(2)(3) 结果:6
* 实现 addFn(1,2)(3) 结果:6
* 实现 addFn(1,2,3) 结果:6
* */
function addFn() {
// 第一次调用 addFn 函数时,将参数保存在数组中
var _args = Array.prototype.slice.call(arguments);
/**内部声明一个函数,利用闭包,保存参数
* @return _fn 返回自己,如果再调用函数, addFn(1,2)(3)这个就会调用两次
* */
var _fn = function(...args) {
_args.push(...args);
return _fn
}
// 利用 toString 隐式转换,执行时隐式转换,返回计算结果
_fn.toString = function() {
return _args.reduce(function(total, item, index) {
return total + item
}, 0)
}
// 返回 _fn 函数
return _fn
}
var r1 = addFn(1,2,3);
var r2 = addFn(1,2)(3);
var r3 = addFn(1)(2)(3);
console.log('r1 :>> ', r1);
console.log('r2 :>> ', r2);
console.log('r3 :>> ', r3);