函数柯里化

151 阅读1分钟

柯里化

在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术

看定义可能有一些懵,写过 bind 的小伙伴应该知道 bind 就是柯里化的典型应用,接受多次参数,返回一个新函数

先来看我们要解决的问题

实现 f 函数,能够按如下方式调用
function add(){
    return a+b+c
}

f(1,2,3)
f(1,2)(3)
f(1)(2)(3)

首先我们可以想到,大概率要返回函数,而且还要记忆接收到的参数,我们可以很容易想到闭包,我们先一步一步推导

假如先实现 f(1,2)(3),我们该怎么做呢?

function add(a,b,c){
    return a+b+c
}

function toCurry(fun){
    return function(){
        const arg=[...arguments]
        return function(){
            const args=[...arg,...arguments]
            return fun.apply(null,args)
        }
    }
}

const f=toCurry(add)
console.log(f(1,2)(3))
//6

由此看来,解题的关键就是闭包+判断参数,这里插播一条小技巧,先上图

image.png

函数(对象)上有一个属性 length,是其参数的数量,我们就可以知道原函数的参数数量,在本题是 3

所以我们可以得出以下通法

function add(a,b,c){
    return a+b+c
}
function toCurry(fun,...arg){
    return function(){
        const args=[...arg,...arguments]
        if(fun.length>args.length){
            return toCurry(fun,...args)
        }else{
            return fun.apply(null,args)
        }
    }
}

const f=toCurry(add)
console.log(f(1,2)(3))
//6

关键就是需要每次合并参数,并设置递归的出口,也就是 else 的逻辑,此时的 args 已经凑齐了所有的参数,可以返回结果