引入:
将使用多个参数的函数转换成一系列使用一个参数的函数的技术
主要用途是可以简化代码结构, 提高系统的可维护性, 一个方法, 只有一个参数, 强制地适应了单一性原则
例子:
function add(a, b, c, d) {
return a + b + c + d;
}
基本调用:
add(1,2,3,4)
在实现柯里化后:
var newadd = Curry(add);
newadd(1,2)(3)(4
固定参数的柯里化
function newFixedCurry(fn) {
// [arr,1,2];
// fn是个类数组
var arr = Array.prototype.slice.call(arguments, 1);
return function () {
var newArg = arr.concat([].slice.call(arguments, 0));
return fn.apply(this, newArg);
}
}
var newAdd = newFixedCurry(add, 1, 2);
var ans = newAdd(2,4); //这个一定要把剩下参数补齐
newFixedCurry的作用就是根据需求, 将参数拆分。实际这个函数做的事情很简单, 将第一次传递的不完全的参数截取出来, 在闭包中保留。 返回一个新的函数, 这个新的函数再次调用的时候, 就会补齐参数, 然后将两次传递进来的参数合并, 在将参数传递给功能函数(add
这就是柯里化的基本雏形!!!
真正的柯里化应该长这样
var newadd = Curry(add);
newadd(1)(2)(3,4)
newadd(1)(2,3,4)
newadd(1,2,3)(4)
实现
function newFixedCurry(fn) {
// [arr,1,2];
// fn是个类数组
var arr = Array.prototype.slice.call(arguments, 1);
return function () {
// arguments [2,3];
var newArg = arr.concat([].slice.call(arguments, 0));
return fn.apply(this, newArg);
}
}
function Curry(fn, length) {
// length
var length = length || fn.length;
return function () {
if (arguments.length < length) {
// 生成一个数组 第一个值是函数,接下来的就是arguments参数值
// [fn,argue]
var combined = [fn].concat([].slice.call(arguments, 0));
return Curry(newFixedCurry.apply(this, combined), length - arguments.length);
} else {
return fn.apply(this, arguments);
}
}
}
试一试:
var newAdd = Curry(add);
var x1 = newAdd(4,2);
var x2 = x1(2,3);
var x3 = x1(4,5);
我们总结下柯里化的好处
降低代码的重复性,提高利用率