美文网首页
函数柯里化

函数柯里化

作者: kevin5979 | 来源:发表于2021-02-06 08:26 被阅读0次
    什么是函数柯里化?
    • 百度百科:在计算机科学中,柯里化(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

    相关文章

      网友评论

          本文标题:函数柯里化

          本文链接:https://www.haomeiwen.com/subject/tpbytltx.html