解释 JavaScript 中函数式编程的概念


主要存在两种编程范式:命令式编程范式和声明式编程范式。函数式编程是声明式范式的一个子类型。范式一词指的是解决特定问题的方法。

函数式编程已经使用了数十年,但在 2015 年 JavaScript 发布了最后一个主要修订版本之后才开始流行起来。使用函数式编程有很多好处,我们将在本教程中讨论这些好处。

函数式编程的不同概念及其优势

函数式编程的工作方式与数学函数的工作方式相同。它允许开发人员基于函数求值来开发软件。这意味着程序员可以将代码分解成小的部分,我们可以称之为函数,从而使代码更容易评估和测试。本教程涵盖了以下函数式编程的概念:

  • 纯函数

  • 代码可读性

  • 代码可维护性和更少的错误

  • 高阶函数

JavaScript 中的纯函数

纯函数

在 JavaScript 中,我们可以编写纯函数。简单来说,纯函数将值作为参数,对其执行某些操作,并返回输出。

纯函数永远不会与其他函数共享任何变量或使用全局变量。

以下是纯函数的属性:

  • 对于给定的输入,纯函数始终返回相同的输出。

  • 纯函数不依赖于任何外部状态 - 纯函数不依赖于任何外部状态或未作为参数传递给它们的变量。

  • 纯函数不会产生任何副作用 - 纯函数不会产生任何副作用,例如修改全局变量或更改外部对象的状态。

您可以通过以下示例更好地了解纯函数。

示例 1

在下面的示例中,我们创建了一个名为 pure_func() 的纯函数,它将值作为参数并将其乘以 2。之后,它打印该值。用户可以看到 pure_func() 没有与其他函数全局共享任何变量。

此外,我们可以在不将其作为纯函数的参数传递的情况下直接使用 global_var。尽管如此,我们还是将其作为参数传递,因为纯函数永远不会共享在函数作用域之外声明的任何变量。

<html>
<body>
   <h2>Pure function in JavaScript</h2>
   <div id = "output"> </div>
   <script>
      let output = document.getElementById("output");
      let global_Var = 56;
      function pure_func(param) {
         param = param*2;
         output.innerHTML += "The Double value of param is " + param + " <br/>";
      }
      pure_func(global_Var);
      pure_func(30);
   </script>
</body>
</html>

代码可读性

由于我们在函数式编程中使用函数编写所有逻辑,因此使我们的代码更具可读性。例如,在其他编程语言中,我们使用 for 或 while 循环遍历数组。但是函数式编程允许我们使用 for-of 循环,这使得代码更具可读性,并告诉其他开发人员我们想要遍历数组并在每个数组元素上执行某些操作。

让我们来看另一个例子。假设我们想从数组中过滤一些值。在其他编程方法中,我们编写一个手动函数来过滤值,但在函数式编程方法中,我们可以使用 filter() 方法,这表明我们想要根据特定逻辑从数组中过滤值。

示例 2

在下面的示例中,我们使用了 filter() 方法来过滤所有能被 10 整除的值。用户可以看到它看起来多么清晰,并且它告诉我们我们想要从数组中过滤某些内容。

现在,让我们看看过滤值的朴素方法。我们使用 for 循环遍历数组,并使用 if 语句检查是否能被 10 整除,并将结果推送到另一个数组。但是,这两个代码都会给出相同的结果,但第一个代码更具可读性。

<html>
<body>
   <h2>Using the <i> filter() </i> method to filter values from the array</h2>
   <div id = "output"> </div>
   <script>
      let output = document.getElementById("output");
      // creating the array of values
      let array = [10, 20, 50, 54, 32, 60, 54];
      output.innerHTML += "Original Array: " + array + "<br>"; 
      // using the functional programming approach to filter 
      //all values which are divisible by 10
      let divisibleBy10 = array.filter((ele) => ele % 10 == 0);
      output.innerHTML += "All values divisible by 10: " + divisibleBy10;
      // using the normal approach to filter values
      let filterValues = [];
      for (let i = 0; i < array.length; i++) {
         let ele = array[i];
         if (ele % 10 == 0) {
            filterValues.push(ele);
         }
      }
   </script>
</body>
</html>

代码可维护性和更少的错误

函数式编程允许我们使代码更易于维护。众所周知,代码重构比编写新代码需要更多时间和成本。此外,开发人员花费更多时间进行代码重构。

从上面给出的最后一个示例中,我们可以理解,编写第二种过滤值的方法需要更多时间才能让其他开发人员理解。因此,如果我们通过函数执行每个逻辑,则可以使代码更具可读性和可维护性。

此外,我们可以通过使用函数式编程来减少错误。正如我们在示例 1 中所看到的,当我们使用函数式方法时,我们无需担心作用域和所有内容。如果任何初学者对作用域没有足够的了解,他们可能会编写充满错误的代码。

此外,代码的每个部分都有其作用域,我们不需要像在面向对象编程语言中那样使用 `this` 关键字来引用作用域。因此,不使用此关键字也可以减少错误。

高阶函数

高阶函数允许我们将函数作为另一个函数的参数传递。例如,我们可以将回调函数作为数组的 reduce() 方法的参数传递。在回调函数中,我们可以编写将数组缩减为单个元素的逻辑。

示例 3

在此示例中,我们使用了 reduce() 方法将数组缩减为单个元素,并将回调函数作为参数传递。它表示高阶函数,因为我们将函数作为参数传递。

<html>
<body>
   <h2>Using the <i>reduce()</i> method to introduce higher order functions</h2>
   <div id="output"></div>
   <script>
      let output = document.getElementById("output");
      // creating the array of values
      let array = [6, 7, 8, 42, 23, 43, 2, 43, 23, 3, 13];
      output.innerHTML = "Original Array: " + array + "<br>";
      // using the array.reduce() method to find the total of the array 
      //and pass the arrow function as an argument of the reduce() method
      let total = array.reduce((total, num) => {
         return total + num;
      });
      output.innerHTML += "The total of the array values: " + total;
   </script>
</body>
</html>

我们学习了函数式编程方法,以及它与编程范式相比如何有益且有所不同。我们了解到,它提供了一种编写可维护且可读的代码的方法,并且错误更少。

更新时间: 2023年1月17日

204 次查看

开启你的 职业生涯

通过完成课程获得认证

开始学习
广告