柯里化原理模拟及总结

一、回顾lodash中curry方法的使用

const _ = require('lodash')
// 需要柯里化的函数
function sum (a, b, c) {
    return a + b + c
}
// 柯里化后的函数
let curried = _.curry(sum)
console.log(curried(1, 2, 3)) // 6
console.log(curried(1, 2)(3)) // 6
console.log(curried(1)(2)(3)) // 6
// curry函数可以将任意多元函数转化为一元函数
复制代码

二、模拟实现curry方法

function curry (func) {
    return function curriedFn(...args) {
        // 判断实参的个数(args.length)是否小于形参的各个数(func.length)
        // 当条件不满足时,说明func需要的参数已经满足,执行func(...args)
        if (args.length < func.length) {
            return function () {                
                // args是闭包中的变量,它保存了函数上一次的传参
                // arguments则是本次调用的传参,两者合并就是累计传参
                // 这里内层函数需要调用外层函数,传入合并后的累计参数
                // 因此给外层函数定义名称为curriedFn,方便调用
                return curriedFn(...args.concat(Array.from(arguments)))
            }
        }
        return func(...args)
    }
}
// 测试功能(通过)
let curried = curry(sum)
console.log(curried(1, 2, 3)) // 6
console.log(curried(1, 2)(3)) // 6
复制代码

三、柯里化总结

  • 柯里化可以让我们给一个函数传递较少的参数,得到一个已经记住某些固定参数的新函数。这是一种对函数参数的缓存。

示例加深理解:

const _ = require('lodash')
// 为了避免声明变量,直接将纯函数匿名后传递给curry
const match = _.curry(function (reg, str) {
    return str.match(reg)
})
// 通过函数柯里化生成了已经记住某些固定参数的新函数
const haveSpace = match(/\s+/g)
const haveNumber = match(/\d+/g)
复制代码
  • 让函数变得更加灵活,让函数的粒度更小

示例:

// 基于上面的示例,定义更细粒度的函数
// 定义lodash函数柯里化的纯函数
const filter = _.curry(function (func, array) {
    return array.filter(func)
})
const findSpace = filter(haveSpace)
复制代码
  • 可以把多元函数转换成一元函数,可以组合使用函数产生强大的功能
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享