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

简介: 【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]: [路由错误]

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

目录
相关文章
|
20天前
|
JavaScript
变量和函数提升(js的问题)
变量和函数提升(js的问题)
|
20天前
|
JavaScript
常见函数的4种类型(js的问题)
常见函数的4种类型(js的问题)
11 0
|
20天前
|
JavaScript
写一个函数将N组<>(包含开始和结束),进行组合,并输出组合结果 (js)
写一个函数将N组<>(包含开始和结束),进行组合,并输出组合结果 (js)
9 0
|
1月前
|
自然语言处理 JavaScript 网络架构
js开发:请解释什么是ES6的箭头函数,以及它与传统函数的区别。
ES6的箭头函数以`=>`定义,简化了函数写法,具有简洁语法和词法作用域的`this`。它无`arguments`对象,不能用作构造函数,不支持`Generator`,且不改变`this`、`super`、`new.target`绑定。适用于简短表达式,常用于异步编程和高阶函数。
17 5
|
1月前
|
JavaScript 前端开发 网络架构
JavaScript 谈谈对箭头函数的理解及其与普通函数的区别。
JavaScript 谈谈对箭头函数的理解及其与普通函数的区别。
17 1
|
1月前
|
前端开发 JavaScript 数据处理
在JavaScript中,什么是异步函数执行的例子
在JavaScript中,什么是异步函数执行的例子
10 0
|
1月前
|
JavaScript
JS封装节流函数
JS封装节流函数
15 0
|
1月前
|
JavaScript 前端开发
javascript箭头函数
javascript箭头函数
|
1月前
|
JavaScript 小程序
微信小程序 wxml 中使用 js函数
微信小程序 wxml 中使用 js函数
70 0
|
1月前
|
JavaScript 前端开发
JavaScript函数科里化
JavaScript函数科里化