柯里化

在计算机中,柯里化是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术
例如:

var foo = function(a) {
return function(b) {
return a * a + b * b;
}
}

(foo(3))(4) 或 foo(3)(4)

柯里化的通用式

  1. 使用ES5的实现
// ES5 的实现
function currying(func, args) {
// 形参个数
var arity = func.length;
// 上一次传入的参数
var args = args || [];

return function () {
// 将参数转化为数组
var _args = [].slice.call(arguments);

// 将上次的参数与当前参数进行组合并修正传参顺序
Array.prototype.unshift.apply(_args, args);

// 如果参数不够,返回闭包函数继续收集参数
if(_args.length < arity) {
return currying.call(null, func, _args);
}

// 参数够了则直接执行被转化的函数
return func.apply(null, _args);
}
}
  1. 使用ES6简化写法
function currying(func, ...args) {

// func.length 是获取一个函数对象的形参的个数,实参的个数用arguments.length
// 如果形参指定的默认值,则只获取指定默认值前面形参的个数
var argLen = func.length
var args = args || []
return function (..._args) {
_args.unshift(...args)
if (_args.length < argLen) {

// 传入的参数数量小于回调函数的形参数量,返回接受剩余参数的函数
return currying.call(null, func, ..._args)
}
return func(..._args)
}
}

运行一下测试用例

// 比如我现在有一个callback的方法,需要指定三个参数
function callback(a, b, c) {
return a + b + c
}
// 如果只需要两个参数,可以给第三个参数一个默认值,因为第三个参数有默认值,func.length值为2
function callback(a, b, c = 0) {
return a + b + c // 相当于 return a + b + 0
}
const r = currying(callback)
r(1,2) // 返回接受剩余参数的新的函数
r(1,2,3) // 6
r(1)(2)(3) // 6
r(1,2,3,4) // r(...)(...)(...) is not a function 参数超过callback的参数报错