JavaScript 柯里化 JavaScript 中的柯里化

2025-05-27

JavaScript 柯里化JavaScript 中的柯里化

柯里化是函数式编程中的一个过程,我们可以将一个带有多个参数的函数转换为一系列嵌套函数。它返回一个以内联方式接收下一个参数的新函数。

换句话说,当一个函数不是一次性接受所有参数,而是接受第一个参数并返回一个接受第二个参数的新函数,然后返回一个接受第三个参数的新函数,依此类推,直到所有参数都得到满足。

也就是说,当我们将函数调用sum(1,2,3)变成sum(1)(2)(3)

函数所采用的参数的数量也称为arity

function sum(a, b) {
    // do something
}
function _sum(a, b, c) {
    // do something
}
Enter fullscreen mode Exit fullscreen mode

函数sum接受两个参数(2 元函数),也_sum接受三个参数(3 元函数)。

柯里化函数是通过链接闭包来构建的,通过同时定义并立即返回其内部函数。

为什么它有用?

  1. 柯里化帮助我们避免一遍又一遍地传递相同的变量。
  2. 它有助于创建高阶函数

柯里化将具有多个参数的函数转换为每个函数采用单个参数的序列/系列函数。

例子:

function sum(a, b, c) {
    return a + b + c;
}
Enter fullscreen mode Exit fullscreen mode
sum(1,2,3); // 6
Enter fullscreen mode Exit fullscreen mode

正如我们所见,函数带有完整的参数。让我们创建一个柯里化版本的函数,看看如何在一系列调用中调用同一个函数(并获得相同的结果):

function sum(a) {
    return (b) => {
        return (c) => {
            return a + b + c
        }
    }
}

console.log(sum(1)(2)(3)) // 6
Enter fullscreen mode Exit fullscreen mode

为了更好地理解它,我们可以将这个和 (1)(2)(3) 分开:

const sum1 = sum(1);
const sum2 = sum1(2);
const result = sum2(3);
console.log(result); // 6
Enter fullscreen mode Exit fullscreen mode

让我们了解一下它是如何工作的:

我们将 1 传递给sum函数:

let sum1 = sum(1);
Enter fullscreen mode Exit fullscreen mode

它返回函数:

return (b) => {
        return (c) => {
            return a + b + c
        }
}
Enter fullscreen mode Exit fullscreen mode

现在, sum1 保存上述接受参数的函数定义 b

我们调用该 sum1 函数并传入 2

let sum2 = sum1(2);
Enter fullscreen mode Exit fullscreen mode

sum1返回第三个函数:

return (c) => {
            return a + b + c
}
Enter fullscreen mode Exit fullscreen mode

返回的函数现在存储在sum2变量中。

sum2将:

sum2 = (c) => {
            return a + b + c
}
Enter fullscreen mode Exit fullscreen mode

sum2使用 3 作为参数调用时,

const result = sum2(3);
Enter fullscreen mode Exit fullscreen mode

它使用之前传入的参数进行计算:a = 1,b = 2 并返回 6。

console.log(result); // 6
Enter fullscreen mode Exit fullscreen mode

最后一个函数只接受c变量,但会使用其他变量执行操作,而这些变量的函数作用域早已返回。尽管如此,它仍然有效,因为Closure🔥

柯里化与偏函数应用

有些人可能会开始认为,柯里化函数的嵌套函数数量取决于它接收的参数数量。没错,这才是柯里化。

让我们举同样的sum例子:

function sum(a) {
    return (b, c) => {
        return a * b * c
    }
}
Enter fullscreen mode Exit fullscreen mode

可以这样调用:

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);
Enter fullscreen mode Exit fullscreen mode

上述函数需要 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)
    }
}
Enter fullscreen mode Exit fullscreen mode

对于 Currying 来说,它会是这样的:

function sum1(x) {
    return (y) = > {
        return (z) = > {
            return sum2(x,y,z)
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

柯里化会根据函数参数的数量创建嵌套函数。每个函数都会接收一个参数。如果没有参数,则不会进行柯里化。

要开发一个接受函数并返回柯里化函数的函数:

function currying(fn, ...args) {
    return (..._arg) => {
        return fn(...args, ..._arg);
    }
}
Enter fullscreen mode Exit fullscreen mode

上述函数接受一个我们想要柯里化的函数 (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
Enter fullscreen mode Exit fullscreen mode

闭包使得 JavaScript 中的柯里化成为可能。希望你对柯里化有了新的认识!

感谢您阅读这篇文章♥️

 如果您有任何疑问,请随时通过 @suprabhasupi与我联系😋

🌟推特 👩🏻‍💻Suprabha.me 🌟 Instagram
文章来源:https://dev.to/suprabhasupi/currying-in-javascript-1k3l
PREV
面向前端开发人员的免费电子书和课程
NEXT
Web 开发人员速查表