什么是柯里化?
英文:currying
柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。
柯里化也可以理解为:提前接收部分参数,延迟执行,不立即输出结果,而是返回一个接受剩余参数的函数。因为这样的特性,也被称为部分计算函数。柯里化,是一个逐步接收参数的过程。
举个例子,假设有一个加法函数:
function add(x, y) {return x + y;
}
我们可以将其柯里化为:
function add(x) {return function(y) {return x + y;}
}
这样,我们就可以通过连续调用返回的函数来实现多参调用:
add(2)(3) // 5
函数柯里化常用于函数式编程,可以帮助我们简化代码、提高代码的复用性和可读性。
柯里化原理
- 创建一个闭包函数,用来保存原始函数和已经部分应用的参数。
- 返回一个新函数,新函数接收一个单独的参数,将它和闭包函数中已经部分应用的参数合并,并调用原始函数。
- 如果新函数接收的参数个数小于原始函数的参数个数,递归调用步骤2,否则返回原始函数的执行结果。
柯里化封装,需要柯里化的函数直接调用该方法:
function sum(a,b,c,d){return a+b+c+d;
}// 把sum(a,b,c,d)转成 sum(a)(b)(c)(d);function curry(cb,arr=[]){return function(...args){let arrs = [...arr,...args];if(arrs.length<cb.length){//判断实参个数是否和原函数的形参个数的关系return curry.call(this,cb,arrs)//调用闭包时,传入arrs,把前面调用的状态进行保持。}else{return cb(...arrs);}}
}let sfn = curry(sum);// let s = sfn(a)(b)(c)(d);
// let s = sfn(1)(2)(3)(4);
// let s = sfn(1,2)(3)(4);
let s = sfn(1,2,3,4);
console.log(s);
该函数接受一个函数作为参数,返回一个新的函数。新函数通过递归调用自身,把参数分解为多个较小的参数列表,最终返回原始函数的结果。
柯里化进阶封装:
const curry = (fn, arr = []) => (...args) => (arg => arg.length === fn.length ? fn(...arg) : curry(fn, arg)
)([...arr, ...args])
curry()函数实际上就是完成了参数的收集和整理,最终,还是调用原函数本身。
柯里化的使用场景:
延迟执行函数:将某些函数的计算推迟到后面再执行,可以使用柯里化来生成一个新的函数,等到需要计算时再调用。
引用部分参数:在某些情况下,我们想保留一部分参数,并在后续的函数调用中重用这些参数。使用柯里化可以生成一个新函数,仅保留传递的参数,而将其他参数预留给稍后调用该函数使用。
函数重用:柯里化还可以用于在多个地方重用同一函数,但是每次使用的参数可能不同。将函数柯里化后,可以重复使用该函数,并传递不同的参数,从而实现代码的重用。
部分应用函数:柯里化还可以用于部分应用函数,即通过对函数进行柯里化,将一个函数转换为另一个函数,该函数仅接受部分参数。这使得我们可以在需要的时候将剩余的参数传递给函数,从而执行该函数。
总的来说,柯里化可以用于任何需要将多个参数的函数转换为单个参数函数的情况。它可以简化代码,使函数更容易重用,并允许更灵活和动态地使用它们。