Javascript 简明教程

JavaScript - Currying

在 JavaScript 中, currying 是一种函数式编程方法,通过该方法可以将接受多个参数的函数转换为一系列函数,每个函数只接受一个参数。柯里化主要用于事件处理和避免将相同的变量作为函数参数多次传递。

How to achieve currying in JavaScript?

在 JavaScript 中,有两种不同的方法可以实现柯里化,如下所示。

  1. Using the closures function

  2. Using the bind() method

Currying using closures

在 JavaScript 中,闭包是一种内部函数可以访问外部函数的变量的技术。为了使用闭包方法实现柯里化,我们可以使用一系列函数,每个函数只接受一个参数。

Syntax

用户可以遵循以下语法,以使用闭包实现柯里化。

function funcName(a) {
   return function (b) {
      // add more functions
      // OR
      return a * b;
   }
}
funcName(a)(b);

在上述语法中,funcName() 函数接受一个参数,并且包含内部函数。内部函数也接受 1 个参数,并且我们在内部函数的主体中使用外部和内部函数的参数。

语法中给出的上述函数类似于以下函数。

function funcName(a, b) {
   return a * b;
}
funcName(a, b);

让我们通过示例来理解柯里化。

Example

在下面的代码中,我们创建了 mul() 函数,它将单个值作为参数并返回将 'b' 作为参数的函数。内部函数还返回另一个函数,该函数将 'c' 作为参数并返回 'a'、'b' 和 'c' 的乘积。

当我们调用 mul(2) 函数时,它会返回整个内部函数,如下所示:

return function (b) {
   return function (c) {
      return a * b * c;
   }
}

当我们调用 mul(2)(3) 函数时:

return function (c) {
return a * b * c;
}

当我们调用 mul(2)(3)(4) 时,它会返回第二个内部函数的结果。

在输出中,你可以看到函数返回结果 24,它是 3 个值的乘积。

<html>
<head>
   <title>JavaScript currying using using closures</title>
</head>
<body>
   <div id = "output"> </div>
   <script>
      // Achieving the currying
      function mul(a) {
         return function (b) {
            return function (c) {
               return a * b * c;
            }
         }
      }
      // Calling the currying function
      let result = mul(2)(3)(4);
      document.getElementById("output").innerHTML = "The result is: " + result;
</script>
</body>
</html>
The result is: 24

通过这种方式,柯里化有助于使代码更加模块化并且可重用,因为它使用高阶函数。每当必须传递等于函数参数数量的参数才能获得准确结果时,柯里化就很有用。例如,如果你不传递上述示例中的 3 个参数,它将不会返回结果。

Currying using bind() method

在 JavaScript 中,bind() 方法用于创建一个新函数并将其存储在变量中。bind() 通常用于对函数的当前参数部分预置参数,从而让你能够有效地对函数进行柯里化。

Syntax

用户可以遵循以下语法使用 bind() 方法在 JavaScript 中实现柯里化。

let multiplyByTwo = multiply.bind(null, 2);
let multiplyByTwoAndThree = multiplyByTwo.bind(null, 3);
multiplyByTwoAndThree(4); // Outputs: 24

在上述语法中,“multiply”是一个可以接受多个参数的函数。我们使用 bind() 方法逐个预置参数,并实现柯里化。

Example

在下面的代码中,multiply() 函数接受 3 个参数并返回乘积结果。“multiply.bind()”向 multiply() 函数添加了一个参数,并返回更新后的函数。类似地,“multiplyByTwoAndThree()”函数存储了带有两个预定义参数的 multiply 函数。

当我们使用单个参数调用“multiplyByTwoAndThree()”函数时,它返回 60,即全部 3 个参数的乘积。

<html>
<head>
   <title>JavaScript currying using bind() method</title>
</head>
<body>
   <div id = "output"> </div>
   <script>
      // Original multiply function that accepts three arguments
      function multiply(x, y, z) {
         return x * y * z;
      }
      // Using the bind() method to achieve currying by partially applying the first argument (2)
      let multiplyByTwo = multiply.bind(null, 2);

      // Further currying by partially applying the second argument (3).
      let multiplyByTwoAndThree = multiplyByTwo.bind(null, 3);

      // Finally calling the curried function with the third argument (10) and outputting the result
      document.getElementById("output").innerHTML = "The result is: " + multiplyByTwoAndThree(10);
   </script>
</body>
</html>
The result is: 60

Use cases of Currying

柯里化技术在实时软件开发中有很多场景,因为它允许代码更模块化和可重复使用。下面,我们给出了柯里化的几个实时用例。

  1. 柯里化可用于处理异步操作,其中函数会返回 Promise。

  2. 它甚至有助于处理某些特定参数部分应用函数的情况,这些参数可以表示事件的当前上下文。

  3. 它允许创建高度可配置的中间件函数,这些函数可以在代码的不同部分使用。