🤔 什么是柯里化?
在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。 —— 百度百科
emmm…读起来有点绕口,没明白是什么意思?别急,我们来举个简单的🌰。
现在我们需要实现一个add函数, 函数执行结果返回三个参数之和。一般情况下,我们会这样写:
function add (x, y, z) {
return x + y + z;
}
add(1, 2, 3);
现在我们有一个新的需求,需要将add函数的调用方式转换成add(1)(2)(3);
这时,我们稍加思索,也能很容易的想到写出下面这种:
function add (x) {
return function (y) {
return function (x) {
return x + y + z;
}
}
}
// es6 简化写法
// const add = x => y => z => (x+y+z);
add(1)(2)(3);
实际上,将add函数进行转换的这个过程,我们就称之为函数柯里化。
⚠️需要注意的是,对于JavaScript语言的函数柯里化概念与 数学和计算机科学中的柯里化概念并无完全一致。通过文章开头百度百科对柯里化的说明,我们能够知道,在计算机科学中,柯里化函数只能接受单一参数,但是在JavaScript语言实际使用柯里化函数时,我们也可以传递一个或多个参数。
这也就是说柯里化之后的add函数,我们也可以这样调用:
add(1, 2)(3);
add(1)(2, 3);
...
显而易见,我们上面重写的add函数并不能满足这种形式的调用;
同时,假如现在我们需要计算add(1)(2)(3)(4)这样的功能,它也是束手无策。
由此可见,我们上面重写的add函数虽然也实现了函数柯里化,但是这并不是我们想要的效果。
🤔那我们怎么才能实现我们想要的柯里化呢?
红宝书上面给了我们一种函数柯里化实现的方法:
function curry(fn){
var args = Array.prototype.slice.call(arguments, 1);
return function (){
var innerArgs = Array.prototype.slice.call(arguments);
var finalArgs = args.concat(innerArgs);
return fn.apply(null, finalArgs);
}
}
function add(num1, num2){
return num1+num2;
}
var cur = curry(add,1);
console.log(cur