JavaScript 柯里化JavaScript 中的柯里化
柯里化是函数式编程中的一个过程,我们可以将一个带有多个参数的函数转换为一系列嵌套函数。它返回一个以内联方式接收下一个参数的新函数。
换句话说,当一个函数不是一次性接受所有参数,而是接受第一个参数并返回一个接受第二个参数的新函数,然后返回一个接受第三个参数的新函数,依此类推,直到所有参数都得到满足。
也就是说,当我们将函数调用sum(1,2,3)
变成sum(1)(2)(3)
函数所采用的参数的数量也称为arity
。
function sum(a, b) {
// do something
}
function _sum(a, b, c) {
// do something
}
函数sum
接受两个参数(2 元函数),也_sum
接受三个参数(3 元函数)。
柯里化函数是通过链接闭包来构建的,通过同时定义并立即返回其内部函数。
为什么它有用?
- 柯里化帮助我们避免一遍又一遍地传递相同的变量。
- 它有助于创建高阶函数
柯里化将具有多个参数的函数转换为每个函数采用单个参数的序列/系列函数。
例子:
function sum(a, b, c) {
return a + b + c;
}
sum(1,2,3); // 6
正如我们所见,函数带有完整的参数。让我们创建一个柯里化版本的函数,看看如何在一系列调用中调用同一个函数(并获得相同的结果):
function sum(a) {
return (b) => {
return (c) => {
return a + b + c
}
}
}
console.log(sum(1)(2)(3)) // 6
为了更好地理解它,我们可以将这个和 (1)(2)(3) 分开:
const sum1 = sum(1);
const sum2 = sum1(2);
const result = sum2(3);
console.log(result); // 6
让我们了解一下它是如何工作的:
我们将 1 传递给sum
函数:
let sum1 = sum(1);
它返回函数:
return (b) => {
return (c) => {
return a + b + c
}
}
现在, sum1
保存上述接受参数的函数定义 b
。
我们调用该 sum1
函数并传入 2
:
let sum2 = sum1(2);
将sum1
返回第三个函数:
return (c) => {
return a + b + c
}
返回的函数现在存储在sum2
变量中。
sum2
将:
sum2 = (c) => {
return a + b + c
}
当sum2
使用 3 作为参数调用时,
const result = sum2(3);
它使用之前传入的参数进行计算:a = 1,b = 2 并返回 6。
console.log(result); // 6
最后一个函数只接受c
变量,但会使用其他变量执行操作,而这些变量的函数作用域早已返回。尽管如此,它仍然有效,因为Closure
🔥
柯里化与偏函数应用
有些人可能会开始认为,柯里化函数的嵌套函数数量取决于它接收的参数数量。没错,这才是柯里化。
让我们举同样的sum
例子:
function sum(a) {
return (b, c) => {
return a * b * c
}
}
可以这样调用:
let x = sum(10);
x(3,12);
x(20,12);
x(20,13);
// OR
sum(10)(3,12);
sum(10)(20,12);
sum(10)(20,13);
上述函数需要 3 个参数并有 2 个嵌套函数,而我们之前的版本则需要 3 个参数并有 3 个嵌套函数。
这个版本不是柯里化。我们只是对函数进行了部分应用sum
。
柯里化和部分应用是相关的(因为闭包),但它们是不同的概念。
部分应用将一个函数转换为另一个具有较小元数的函数。
function sum1(x, y, z) {
return sum2(x,y,z)
}
// to
function sum1(x) {
return (y,z) => {
return sum2(x,y,z)
}
}
对于 Currying 来说,它会是这样的:
function sum1(x) {
return (y) = > {
return (z) = > {
return sum2(x,y,z)
}
}
}
柯里化会根据函数参数的数量创建嵌套函数。每个函数都会接收一个参数。如果没有参数,则不会进行柯里化。
要开发一个接受函数并返回柯里化函数的函数:
function currying(fn, ...args) {
return (..._arg) => {
return fn(...args, ..._arg);
}
}
上述函数接受一个我们想要柯里化的函数 (fn) 和一个可变数量的参数 (...args)。rest 运算符用于将 fn 后面的参数数量汇总到 ...args 中。
接下来,我们返回一个函数,该函数也将其余参数收集为 ..._args。该函数通过使用展开运算符传入 ...args 和 ..._args 作为参数,调用原始函数 fn,然后将值返回给用户。
现在,我们可以使用上述函数来创建 curry 函数。
function sum(a,b,c) {
return a + b + c
}
let add = currying(sum,10);
add(20,90); // 120
add(70,60); // 140
闭包使得 JavaScript 中的柯里化成为可能。希望你对柯里化有了新的认识!
感谢您阅读这篇文章♥️
如果您有任何疑问,请随时通过 @suprabhasupi与我联系😋
文章来源:https://dev.to/suprabhasupi/currying-in-javascript-1k3l