一、回顾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