函数柯里化

什么是函数柯里化?
  • 百度百科:在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。
  • 通俗点说就是将一个函数拆分成多个函数,是固定部分参数,返回一个接受剩余参数的函数,也称为部分计算函数,目的是为了缩小适用范围,创建一个针对性更强的函数。

需求:分步计算四个数字的相加

function add(a, b, c, d) {
  return a + b + c + d;
}

// 参数柯里化
function FixedParmasCurry(fn) {
  let _arg = [].slice.call(arguments, 1) // 第一次获得参数
  return function () {  // 返回新的函数
    let newArg = _arg.concat([].slice.call(arguments, 0))  // 参数合并
    return fn.apply(this, newArg);  // 执行函数
  }
}

var newAdd = FixedParmasCurry(add,2,3);
console.log(newAdd(2,3))  // 10
  • 问题: 以上代码只是实现了两步的相加,没有真正实现柯里化
  • 实现 add(2)(3)(1)(4) 模式代码
function add(a, b, c, d) {
  return a + b + c + d;
}

function FixedParmasCurry(fn) {
  let _arg = [].slice.call(arguments, 1)
  return function () {
    let newArg = _arg.concat([].slice.call(arguments, 0))
    return fn.apply(this, newArg);
  }
}


function Curry(fn, length) {
 //  获得函数的参数剩余长度
  length = length || fn.length;
  return function () {
    if (arguments.length < length) { // 参数不足
      let combined = [fn].concat([].slice.call(arguments, 0)) // [fn,1] [fn,2] ...
      return Curry(FixedParmasCurry.apply(this, combined), length - arguments.length) // 递归
    } else {
      return fn.apply(this, arguments)
    }
  }
}

let newAdd = Curry(add);
let res = newAdd(1)(2)(3)(4)
console.log(res);  // 10
关于curry的一些性能问题
  • 存取arguments对象通常要比存取命名参数要慢一点
  • 使用fn.apply通常比直接调用稍微慢点
  • 创建大量嵌套作用域和闭包函数会带来花销,无论是在内存还是速度上
  • 不过对于这些,js的性能损耗基本是可以忽略不计的,所以curry是可以直接放心的使用。
END

你可能感兴趣的:(函数柯里化)