在记忆中,柯里化应该是个经常在面试中出现的人儿
概念
什么是柯里化?
偷窃下大家的例子
function add (x, y) {
return (x + y)
}
上面我们定义了一个求两数之和的函数,我们一般如下使用它
add(1, 2) // 3
将 add 柯里化之后
const curriedAdd = curry(add)
curriedAdd(1) // Function
curriedAdd(1)(2) // 3
从以上例子可以看出,柯里化是什么呢?
就是实现只传递给函数部分参数,使其返回函数,可以继续传递参数来调用,只有当参数达到函数形参数量时才真正调用函数得到结果
使用场景
在我们调用一个函数的时候,可能会出现多次调用的前置参数相同情况,如
ajax('appUrl', { ata: 1 })
ajax('appUrl', { ata: 2 })
ajax('appUrl', { ata: 3 })
如果有了柯里化
const appAjax = curry(ajax, 'appUrl')
appAjax({ ata: 1 })
appAjax({ ata: 2 })
appAjax({ ata: 3 })
现在我们就不再需要重复传入参数 appUrl 了,函数调用更加简洁易维护(强行解释一波)
实现
function curry (fn, ...args) {
if (fn.length > args.length) {
return (...args2) => {
return curry(fn, ...args, ...args2)
}
}
return fn(...args)
}
上面是实现的代码,看起来比较简单,但可能不是那么容易理解,主要用到了闭包和递归
下面说说实现思路
-
函数柯里化其实主要就是处理参数,通过参数的长度来判断执行函数还是返回函数继续接收参数
-
所以第一步比较现有参数和函数所需参数
-
如果现有参数小于函数所需参数,则返回函数继续接收参数
return (...args2) => {} -
返回的函数继续接收参数,此时我们并不知道此函数接收的参数是否会满足所需参数,所以需要将接收的参数和现有参数组合再次柯里化
return curry(fn, ...args, ...args2) -
如果在递归的柯里化函数中,接收到的参数已经满足所需参数,则直接返回函数执行结果即可
return fn(...args)
函数效果演示
curry(add)(1)(2)(3) // 6
curry(add)(1,2)(3) // 6
curry(add)(1)(2, 3) // 6
curry(add, 1)(2, 3) // 6
curry(add, 1)()()(2, 3) // 6
参考
欢迎来前端学习打卡群一起学习~516913974