面试中级前端,你不知道柯里化?

335 阅读2分钟

在记忆中,柯里化应该是个经常在面试中出现的人儿

概念

什么是柯里化?

偷窃下大家的例子

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)
}

上面是实现的代码,看起来比较简单,但可能不是那么容易理解,主要用到了闭包和递归

下面说说实现思路

  1. 函数柯里化其实主要就是处理参数,通过参数的长度来判断执行函数还是返回函数继续接收参数

  2. 所以第一步比较现有参数和函数所需参数

  3. 如果现有参数小于函数所需参数,则返回函数继续接收参数return (...args2) => {}

  4. 返回的函数继续接收参数,此时我们并不知道此函数接收的参数是否会满足所需参数,所以需要将接收的参数和现有参数组合再次柯里化return curry(fn, ...args, ...args2)

  5. 如果在递归的柯里化函数中,接收到的参数已经满足所需参数,则直接返回函数执行结果即可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