定义
在计算机科学中,柯里化把接受多个参数的函数编程变为接受一个单一的参数(最初函数的第一个参数)的函数,并且返回接收余下的参数且返回结果的新函数的技术(缩小适用范围,创建一个针对性更强的函数)。
test(1, 2, 3);test(1)(2)(3);test(1, 2)(3);test(1)(2, 3);
柯里化后,在未收够原函数的参数个数时只会返回一个新的函数,直接参数够时才返回值。
用途
- 功能内聚
- 降低耦合
- 降低代码的重复性
- 提高代码的适应性
柯里化的实现例子
```javascript function add(a, b, c, d) { // 使其柯里化 return a + b + c + d; }
var curry2Add = progressCurrying(add); // 有达到的目标,与偏函数相似 console.log(carry2Add(1, 2, 3)(4));
// 实现转为柯里化函数 // 在未收够原函数的参数个数时只会返回一个新的函数 function progressCurrying(fn, args) { var _this = this, len = fn.length, //原函数形参长度 args = args || []; //参数收集数据
return function () {_args = [].slice.call(arguments);// 加入本次收集到的参数args = args.concat(_args);// 如果参数个数小于最初的fn.length,则递归调用,继续收集参数if (args.length < len) {return progressCurrying.call(_this, fn, args);}// 参数收集完毕,则执行fnreturn fn.apply(_this, args);};
}
<a name="wPie0"></a># 反柯里化让当前的函数不局限于其调用者本身,让函数更加的通用性和泛化(扩大适用范围)。这就是反柯里化解决的问题。如 Array.prototype.push ,这个方法作用对象数组。<br />可以通过 .call / .apply 的方式更改作用对象,使其对一个类数组对象。```javascriptFunction.prototype.uncurrying = function(){var fn = this;return function(){var _this = Array.prototype.shift.call(arguments);return fn.apply(_this, arguments);}}// 另一种写法是使用 bindFunction.prototype.uncurrying = function(){return Function.prototype.call.bind(this);}var push = Array.prototype.push.uncurrying();var obj = {};console.log(push(obj, 'first', 'second')); // 2console.log(obj) // {0:"first", 1:"second", length:2}
总结
函数柯里化就是对高阶函数的降阶处理,缩小适用范围,创建一个针对性更强的函数
function(arg1, arg2) // => function(arg1)(arg2)function(arg1, arg2, ... argN) // => function(arg1)(arg2)...(argN)
反柯里化就是反过来,增加适用范围,让方法使用场景更大
obj.func(arg1, arg2) // => func(obj, arg1, arg2)
也能这样理解
柯里化是在运算前提前传参,可以传递多个参数;
反柯里化是延迟传参,在运算时把原来已经固定的参数或者this上下文等当作参数延迟到未来传递。
