【JavaScript】函数式编程——函数柯里化

JavaScript中的函数柯里化

柯里化的定义与理解:

柯里化也是属于函数式编程里面一个非常重要的概念。
维基百科定义:

  • 在计算机科学中,柯里化,又以为卡瑞化或加里化;
  • 是把接收多个参数的函数,变成一个接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数,而且返回结果的新函数的技术;
  • 柯里化生声称“如果你固定某些参数,你讲得到接受余下参数的一个函数”。

个人理解小总结:
只传递给函数一个部分参数来调用它,让它返回一个函数去处理剩余的参数,这个过程称为柯里化。

如下示例代码展示了什么是函数柯里化:

// 正常情况下 代码
function sum1 (num1, num2, num3) {
    
    
    return num1 + num2 + num3
}
var result1 = sum2(1, 2, 3)
console.log(result1) // 6

// 函数柯里化
function sum2 (num1) {
    
    
    return function sum3 (num2) {
    
    
        return function sum4 (num3) {
    
    
            return num1 + num2 + num3
        }
    }
}
var result2 = sum2(1)(2)(3)
console.log(result2) // 6

// 简化柯里化代码 (其实就是使用箭头函数简写)
var sum3 = x => y => z => {
    
    
    return x + y + z
}
var result3 = sum3(1)(2)(3)
console.log(result3) // 6

看完上述示例代码后有什么想法呢?
我明明可以一步写完就像第一段代码那样,我干嘛还要柯里化,写成第二段那样麻烦。
接下来就为大家解疑:

  • 在函数式编程中,我们其实往往希望一个函数处理的问题尽可能的单一,而不是将一大堆的处理过程交给一个函数来处理;
  • 那么我们是否就可以将每次传入的参数在单一的函数中进行处理,处理完后在下一个函数中再使用处理后的结果。让函数的职责单一。
  • 并且经过柯里化的函数有的地方可以直接进行逻辑复用。

使用柯里化的好处一:单一职责的原则

还是利用上面的代码进行描述
现在我们修改约束条件为:将第一个参数加上2,第二个参数乘以2,第三个参数平方
如下示例代码展示了,函数柯里化的单一职责原则:

// 方式一:正常情况下我们会将简单的处理逻辑这样写(代码逻辑很少)
// 但是如果num1的处理逻辑有20行 ,num2的处理逻辑有20行 ,num3的处理逻辑有20行 ,这样处理起来函数会变得很复杂,之后要修改也不容易去操作
function sum1 (num1, num2, num3) {
    
    
    num1 = num1 + 2
    num2 = num2 * 2
    num3 = num3 * num3
    return num1 + num2 + num3
}
var result1 = sum1(1, 2, 3)
console.log(result1) // 16

// 方式二:
// 函数柯里化单一职责原则,每一个函数中都有一个对应的职责,修改起来也很方便
function sum2 (num1) {
    
    
    num1 = num1 + 2
    return function (num2) {
    
    
        num2 = num2 * 2
        return function (num3) {
    
    
            num3 = num3 * num3
            return num1 + num2 + num3
        }
    }
}
var result2 = sum2(1)(2)(3)
console.log(result2) // 16

两种方式的输出结果一致,但第二种使用了柯里化实现了单一职责原则

使用柯里化的好处二:逻辑的复用

案例一: 假设在程序中,需要经常把5和一个数值相加的出结果,实现方法示例代码如下:

// 方式一:
function sum (x, y) {
    
    
    return x + y
}
console.log(sum(5, 1))
console.log(sum(5, 2))

// 方式二:函数柯里化
function add (num1) {
    
    
    return function (num2) {
    
    
        return num1 + num2
    }
}
// 使用方法一:
var result1 = add(5)(10)
console.log(result1) // 15
// 使用方法二:直接将add(5)存储在一个变量中,使用的时候只需要传入要与5相加的数字
var add5 = add(5)
var result2 = add5(10)
console.log(result2) // 15

案例二: 假设在程序中,需要打印日志获取时间,类型,文本描述,示例代码如下:

// 方式一:
function log1 (date, type, message) {
    
    
    console.log(`[${
      
      date.getHours()}:${
      
      date.getMinutes()}][${
      
      type}]: [${
      
      message}]`)
}
log1(new Date(), 'debug', '参数错误') // [22:49][debug]: [参数错误]
log1(new Date(), 'future', '新增功能') // [22:49][future]: [新增功能]

// 方式二: 函数柯里化 
var log2 = date => type => message => {
    
    
    console.log(`[${
      
      date.getHours()}:${
      
      date.getMinutes()}][${
      
      type}]: [${
      
      message}]`)
}
log2(new Date())('debug')('参数错误') // [22:49][debug]: [参数错误]
log2(new Date())('future')('新增功能') // [22:49][future]: [新增功能]

// (1)函数柯里化 - 逻辑复用,假设当前日志打印都是获取的当前时间,柯里化代码优化为:
var logDate = log2(new Date())
logDate('debug')('参数错误') // [22:49][debug]: [参数错误]
logDate('future')('新增功能') // [22:49][future]: [新增功能]


// (2)函数柯里化 - 逻辑复用,假设当前日志打印都是获取的当前时间与类型都为debug,柯里化代码优化为:
var logDateAndType = log2(new Date())('debug')
logDateAndType('参数错误') // [22:49][debug]: [参数错误]
logDateAndType('路由错误') // [22:49][debug]: [路由错误]

看完全文是不是对柯里化有了深入的了解,如果感觉文章写得不错,就点个赞吧。下一篇文章更新柯里化的实现原理哦,拥有自动实现函数柯里化的方法。

猜你喜欢

转载自blog.csdn.net/qq_49002903/article/details/124762212