一、什么是函数柯里化?
1、柯里化?
我第一眼看到它的想到的是:这名字也太高端了吧,这不会哪个伟人又整了什么高等数学的定理要我学?还好我的"闺蜜"之一(仅是我单方面认定的闺蜜关系) - - 维基百科,告诉了它的真实身份。
柯里化,英语:Currying(满满的英译中的既视感),是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。
- 庆幸 柯里化 不是什么要求证的高等数学公式,
- Currying 有个意思是,局部套用;
- 浅显分析:原来调用函数时一个括号里多个实参,函数柯里化就是,将实参逐个分开(类似 add(3,4) -->add(3)(4),实现返回两数相加的结果,这里也就是7)
- 如果是你,你会怎么实现柯里化函数 add(3)(4) 呢?
2、如何实现add(3)(4) ?
个人觉得可从以下方面切入:
- 首先我会想到用递归:因为有个累加的过程,并且是同一个函数
- 还有根据我闺蜜的解释:要返回一个函数,
纯个人体会啊(没理没据),知道真相的大佬欢迎来指点我:
这个函数柯里化,有点像那个Promise(从一个个大括号 { } 包含 的 编码形式,变成了then()的链式编码格式),它返回的数据类型也是它本身
二、实现函数柯里化
直接看代码:
- 满足了返回函数的切入点,
- 没有使用到递归思想
- 运用到了 - - 闭包
function add(a,b){
return a + b;
}
console.log(add(3,4)); // 7
// 函数柯里化
function curryAdd(a){
return function(b){
return a+b;
}
}
console.log(curryAdd(3)(4)); //7
从结果上看,算是实现了函数柯里化。
三、增强版的curryAdd( )
需求:如果是三个参数呢?或者说参数个数由使用者确定,想几个数相加就传几次实参?
(以下代码不准确)
function add() {
// 保存所有的参数,
var _args = Array.prototype.slice.call(arguments);
var _adder = function () {
// 收集链式括号里的参数
_args.push(...arguments);
// 这里有递归了,这也是使用函数表达定义函数的原因
return _adder;
};
return _adder;
console.log(_args);
}
console.log(add(3)(4)(5));
这是我能想到最完美的方法了,但是相加的结果的结果没办法获取···,(问题在于只能return 一个值啊,,,,)
我参考了我另一个闺蜜–baidu 的解决思路:重写toString()办法!真是太妙了!我是没想到,
而且还能计算:
- add(3)(4)(5);
- add(3,4)(6);
- add(3)(5,6);
function add() {
// 保存所有的参数,
var _args = Array.prototype.slice.call(arguments);
var _adder = function () {
// 收集链式括号里的参数
_args.push(...arguments);
// 这里有递归了,这也是使用函数表达定义函数的原因
return _adder;
};
// console.log("args:",_args);
_adder.toString = function () {
return _args.reduce(function (a, b) {
return a + b;
});
}
return _adder;
}
console.log(add(3)(4)(5)); // 12