柯里化函数的了解和实现

柯里化属于函数式编程里面一个非常重要的概念:把多个参数的函数,变成接受一个单一参数的函数,并返回接受余下的参数,而且返回结果的新函数的技术

简单来说:只传递给函数一部分参数来调用它,让他返回一个函数去处理剩余的参数,这个过程称为柯里化

function add(x, y, z) {
  return x + y + z
}

var result = add(10, 20, 30)
console.log(result)

function sum1(x) {
  return function(y) {
    return function(z) {
      return x + y + z
    }
  }
}

var result1 = sum1(10)(20)(30)
console.log(result1)

// 简化柯里化的代码
var sum2 = x => y => z => {
  return x + y + z
}

console.log(sum2(10)(20)(30))

var sum3 = x => y => z => x + y + z
console.log(sum3(10)(20)(30))

柯里化的存在意义是什么?

在函数式编程中,我们其实往往希望一个函数处理的问题尽可能的单一,而不是将一大堆的处理过程交给一个函数来处理

我们是否就可以将每次传入的参数在单一的函数中进行处理,处理完后在下一个函数中再处理后的结果

柯里化的重点--普通函数转化为柯里化函数

function add1(x, y, z) {
  return x + y + z
}
// 柯里化函数的实现hyCurrying
function hyCurrying(fn) {
  return function(...args) {
    // 判断当前已经接收的参数的个数, 可以参数本身需要接受的参数是否已经一致了
    // 1.当已经传入的参数 大于等于 需要的参数时, 就执行函数
    if (args.length >= fn.length) {
      return fn.apply(this, args)
    } else {
      // 没有达到个数时, 需要返回一个新的函数, 继续来接收的参数
      return function(...args2) {
        // 接收到参数后, 需要递归调用curried来检查函数的个数是否达到
        return curried.apply(this, args.concat(args2))
      }
    }
  }
}
var curryAdd = hyCurrying(add1)
// console.log(curryAdd(10, 20, 30)) // 直接运行
// console.log(curryAdd(10, 20)(30)) // 递归两次
console.log(curryAdd(10)(20)(30)) //递归三次

 柯里化函数运用了设计模式的单一职责原则,一个函数只对当前的对象做处理

 


此处对组合函数进行一个理解 

先放上一个简单的组合函数

 

function double(num) {
  return num * 2
}

function square(num) {
  return num ** 2
}

var count = 10
var result = square(double(count))
console.log(result)

// 实现最简单的组合函数
function composeFn(m, n) {
  return function(count) {
    return n(m(count))
  }
}

var newFn = composeFn(double, square)
console.log(newFn(10))

 下面是通用的组合函数实现,暂时先放这里,我也还没理清楚逻辑

function hyCompose(...fns) {
  var length = fns.length
  // 判读传值是否是函数,不是就弹出错误
  for (var i = 0; i < length; i++) {
    if (typeof fns[i] !== 'function') {
      throw new TypeError("Expected arguments are functions")
    }
  }

  return function(...args) {
    var index = 0
    var result = length ? fns[index].apply(this, args): args
    while(++index < length) {
      result = fns[index].call(this, result)
    }
    return result
  }
}

function double(m) {
  return m * 2
}

function square(n) {
  return n ** 2
}

var newFn = hyCompose(double, square)
console.log(newFn(10))

 感谢coderwhy老师

posted @ 2021-09-28 14:42  爱学习的兔子  阅读(181)  评论(0)    收藏  举报