将使用多个参数的函数转换成一系列使用一个参数的函数的技术。

主要用途是可以简化代码结构, 提高系统的可维护性, 一个方法, 只有一个参数, 强制地适应了单一性原则。

固定参数的柯里化

function add(a, b, c, d) {
    return a + b + c + d
}
function fixedParamsCurry(fn) {
    var _args = [].slice.call(arguments, 1)
    return function () {
        var newArgs = _args.concat([].slice.call(arguments, 0))
        return fn.apply(this, newArgs)
    }
}
var newAdd = fixedParamsCurry(add, 1, 2)
console.log(newAdd(3,4)); // 10

fixedParamsCurry的作用就是根据需求, 将参数拆分。实际这个函数做的事情很简单, 将第一次传递的不完全的参数截取出来, 在闭包中保留。 返回一个新的函数, 这个新的函数再次调用的时候, 就会补齐参数, 然后将两次传递进来的参数合并, 在将参数传递给功能函数(add)

这就是柯里化的基本雏形。

真正的柯里化应该长这样

function curry(){}
newAdd = curry(add)
newAdd(1)(2)(3)(4)
newAdd(1)(2, 3)(4)
newAdd(1, 2, 3)(4)

实现

function fixedParamsCurry(fn) {
    var _args = [].slice.call(arguments, 1)
    return function () {
        var newArgs = _args.concat([].slice.call(arguments, 0))
        return fn.apply(this, newArgs)
    }
}
function Curry(fn, length) {
    var len = length || fn.length
    return function () {
        if (arguments.length < len){   // 参数小于既定需要的参数
            // 如果上一次传递了 1 2,  [fn, 1, 2]
            var combined = [fn].concat([].slice.call(arguments, 0))
            return Curry(fixedParamsCurry.apply(this, combined), len - arguments.length)
        } else { // 参数传递完毕
            return fn.apply(this, arguments)
        }
    }
}
function add(a, b, c, d) {
    return a + b + c + d
}
var newAdd = Curry(add, 4)
console.log(newAdd(1, 2)(3)(4)); // 10