11-在函数中返回函数
13.6.3 在函数中返回函数
在一个函数中返回另一个函数恐怕是函数所有用法中最难懂的一个了,但它非常有用,可以把从函数中返回函数看成3D打印机:它自己制造一些东西(像函数一样),然后这些东西还可以继续制造东西。激动人心的是,可以定制返回函数:类似于可以定制3D打印机打印出的东西。
回想一下之前的 sum 函数,它有一个可选的函数参数,该函数会在求和之前对数组中每一个元素做一些操作。还记得之前提到过,如果有需要,可以创建一个名为 sumOfSquares 的独立函数。假设现在就需要这样一个函数。但是,一个函数的参数中又有数组,又有函数是不太好的:需要的显然是一个只接收一个数组作为参数的函数,而返回的是平方和。(如果想知道什么时候这种假设会成立,考虑这样一个API,它允许提供一个 sum 函数,但它只接收具有单个参数的函数)
其中一种实现方式是创建一个新函数,让该函数调用原来的函数。
function sumOfSquares(arr) {
return sum(arr, x => x*x);
}
需要的只是一个函数时,这种方式固然不错。但如果需要不断重复这种模式呢?一个有效的解决方案可能是,创建一个返回特定函数的函数:
function newSummer(f) {
return arr => sum(arr, f);
}
新的函数 newSummer 创建了一个只接收一个自定义函数作为唯一参数的求和函数。下面看看如何使用它进行不同种类的求和运算:
const sumOfSquares = newSummer(x => x*x);
const sumOfCubes = newSummer(x => Math.pow(x, 3));
sumOfSquares([1, 2, 3]); // 返回 14
sumOfCubes([1, 2, 3]); // 返回 36
把接收多个参数的函数转换成接收单个参数的函数的技术叫作柯里化(currying),该名字出自于它的开发者:美国数学家Haskell Curry。
在函数中返回函数的应用程序通常都很深奥难懂。如果想看更多的例子,可以看看Express或者Koa(流行的JavaScript web开发框架)的中间件。一般来说,中间件就是一个返回函数的函数。
把接收多个参数的函数转换成接收单个参数的函数的技术叫作柯里化(currying),该名字出自于它的开发者:美国数学家Haskell Curry。