Maison  >  Article  >  interface Web  >  Introduction détaillée à la programmation fonctionnelle utilisant JavaScript (1) (photo)

Introduction détaillée à la programmation fonctionnelle utilisant JavaScript (1) (photo)

黄舟
黄舟original
2017-03-11 15:07:141486parcourir

Cet article est le premier article de la série sur la programmation fonctionnelle. Ici, je présenterai brièvement le paradigme de programmation, puis passerai directement au concept de programmation fonctionnelle utilisant Javascript, puisque JavsScript est l'un des langages de programmation fonctionnelle les plus reconnus. Les lecteurs sont encouragés à en apprendre davantage sur ce concept fascinant à travers la section Références.

Paradigme de programmation

Un paradigme de programmation est un cadre composé d'outils permettant de réfléchir à un problème et de réaliser une vision du problème. De nombreux langages modernes sont polyparadigmes (ou multi-paradigmes) : ils prennent en charge de nombreux paradigmes de programmation différents, tels que l'orientation objet, la métaprogrammation, la fonctionnelle, la procédurale, etc.

使用 JavaScript 进行函数式编程 (一)

Paradigme de programmation fonctionnelle

La programmation fonctionnelle est comme une voiture à hydrogène : avancée et futuriste, mais pas encore largement adoptée. Contrairement à la programmation impérative, elle consiste en une séquence d'instructions qui mettent à jour l'état global au moment de l'exécution. La programmation fonctionnelle transforme les calculs en évaluations d'expressions. Ces expressions sont toutes composées de fonctions mathématiques pures de première classe (peuvent être utilisées et traitées comme des valeurs normales) et n'ont aucun effet secondaire.

使用 JavaScript 进行函数式编程 (一)

La programmation fonctionnelle met l'accent sur les valeurs suivantes :

Les fonctions sont une priorité de premier ordre

Nous devons traiter les fonctions avec d'autres éléments dans un langage de programmation, les objets de classe sont traités de la même manière. En d’autres termes, vous pouvez stocker des fonctions dans des variables, créer des fonctions de manière dynamique et renvoyer des fonctions ou transmettre des fonctions à d’autres fonctions. Regardons un exemple...

使用 JavaScript 进行函数式编程 (一)

Une chaîne peut être enregistrée en tant que variable, tout comme les fonctions, par exemple :

var sayHello = function() { return “Hello” };

A la chaîne peut Enregistrer en tant que champ d'objet, des fonctions peuvent également être utilisées, par exemple :

var person = {message: “Hello”, sayHello: function() { return “Hello” }};

Une chaîne ne peut être créée que lorsqu'elle est à nouveau utilisée, des fonctions peuvent également être utilisées, par exemple :

“Hello ” + (function() { return “World” })(); //=> Hello World

Une chaîne peut être enregistrée Si elle est passée comme paramètre d'entrée à une fonction, la fonction peut également être :

    function hellloWorld(hello, world) { return hello + world() }

Une chaîne peut être utilisée comme valeur de retour de fonction, et la fonction peut aussi être, par exemple :

return “Hello”;
return function() { return “Hello”};

Cas avancé

使用 JavaScript 进行函数式编程 (一)

Si une fonction prend d'autres fonctions comme paramètres d'entrée ou comme valeurs de retour, elle est appelée une fonction d’ordre supérieur. Nous venons de voir un exemple de fonction d'ordre supérieur. Examinons ensuite une situation plus complexe.

Exemple 1:

[1, 2, 3].forEach(alert);
// alert 弹窗显示“1" 
// alert 弹窗显示 "2" 
// alert 弹窗显示 "3”

Exemple 2:

function splat(fun) {
   return function(array) {
        return fun.apply(null, array);
   };
}
var addArrayElements = splat(function(x, y) { return x + y });
addArrayElements([1, 2]);
//=> 3

FavorisFonctions pures

使用 JavaScript 进行函数式编程 (一)

Les fonctions pures n'auront pas d'autres effets secondaires. Les soi-disant effets secondaires font référence aux effets des fonctions sur. fonctions Modification de l'état extérieur. Par exemple :

  • Modifier une variable

  • Modifier la structure des données

  • Modifier une variable de le monde extérieur Définir un champ

  • Lance une exception ou affiche un message d'erreur

L'exemple le plus simple est une fonction mathématique. La fonction Math.sqrt(4) renvoie toujours 2. Il n'utilisera aucune autre information de refroidissement, telle que l'état ou les paramètres de réglage. Les fonctions mathématiques ne provoquent jamais d'effets secondaires.

Évitez de modifier l'état

使用 JavaScript 进行函数式编程 (一)

La programmation fonctionnelle prend en charge les fonctions pures. De telles fonctions ne peuvent pas modifier les données, elles sont donc principalement utilisées pour créer des données immuables. De cette façon, il n'est pas nécessaire de modifier une structure de données existante et elle peut en créer une nouvelle efficacement.

Vous voudrez peut-être savoir si une fonction pure produit une valeur de retour immuable en modifiant certaines données locales. , Est-ce autorisé ? La réponse est oui.
Très peu de types de données en JavaScript sont immuables par défaut. La chaîne est un exemple de type de données qui ne peut pas être modifié :

   var s = "HelloWorld";
    s.toUpperCase();
    //=> "HELLOWORLD"
    s;
    //=> "HelloWorld"

Avantages de l'état immuable

• Éviter la confusion et augmenter la précision du programme : dans les systèmes complexes, le plus difficile Le bug compris est causé par la modification de l'état par le code client externe dans le programme.
• Établir une programmation multithread "rapide et concise" : si plusieurs threads peuvent modifier la même valeur partagée, vous devez obtenir la valeur de manière synchrone. Il s’agit d’un défi de programmation fastidieux et sujet aux erreurs pour les experts.
La mémoire transactionnelle logicielle et le modèle Actor permettent un traitement direct des modifications de manière thread-safe.

Utilisez la récursivité au lieu des appels en boucle

使用 JavaScript 进行函数式编程 (一)

递归是最有名的函数式编程技术。如果您还不知道它的话,那么可以理解为递归函数就是一个可以调用自己的函数。

替代反复循环的最经典方式就是使用递归,即每次完成函数体操作之后,再继续执行集合里的下一项,直到满足结束条件。递归还天生符合某些算法实现,比如遍历树形结构(每个树枝都是一颗小树)。

在任何语言里,递归都是一项重要的函数式编程方式。很多函数语言甚至要求的更加严格:只支持递归遍历,而不支持显式的循环遍历。这需要语言必须保证消除了尾端调用,这是 JavasSrip 不支持的。

惰性求值优于激进计算

使用 JavaScript 进行函数式编程 (一)

数学定义了很多无穷集合,比如自然数(所有的正整数)。他们都是符号表示。任意特定有限的子集都在需要时求值。我们将其称之为惰性求值(也叫做非严格求值,或者按需调用,延迟执行)。及早求值会强迫我们表示出所有无穷数据,而这显然是不可能的。

很多语言都默认是惰性的,有些也提供了惰性数据结构以表达无穷集合,并在需要时对自己进行精确计算。

很明显一行代码 result = compute() 所表达的是将 compute() 的返回结果赋值给 result。但是 result 的值究竟是多少只有其被用到的时候才有意义。

可见策略的选择会在很大程度上提高性能,特别是当用在链式处理或者数组处理的时候。这些都是函数式程序员所喜爱的编程技术。

这就开创可很多可能性,包括并发执行,并行技术以及合成。

但是,有一个问题,JavaScrip 并不对自身进行惰性求值。话虽如此,Javascript 里的函数库可以有效地模拟惰性求值。

闭包的全部好处

所有的函数式语言都有闭包,然而这个语言特性经常被讨论得很神秘。闭包是一个函数,这个函数有着对内部引用的所有变量的隐式绑定。换句话说,该函数对它引用的变量封闭了一个上下文。JavaScript 中的闭包是能够访问父级作用域的函数,即使父级函数已经调用完毕。

   function multiplier(factor) {
      return function(number) {
          return number * factor;
      };
   }
  var twiceOf = multiplier(2);
    console.log(twiceOf(6));
//=> 12

声明式优于命令式编程

函数式编程是声明式的,就像数学运算,属性和关系是定义好的。运行时知道怎么计算最终结果。阶乘函数的定义提供了一个例子:

factorial(n)       = 1 if n = 1

                            n * factorial(n-1) if n > 1

该定义将 factorial(n) 的值关联到 factorial(n-1),是递归定义。特殊情况下的 factorial(1) 终止了递归。

var imperativeFactorial = function(n) {
    if(n == 1) {
        return 1
    } else {
        product = 1;
        for(i = 1; i <= n; i++) {
              product *= i;
        }
        return product;
     }
}
var declarativeFactorial = function(n) {
       if(n == 1) {
             return 1
       } else {
             return n * factorial(n - 1);
      }
  }

从它实现阶乘计算来看,声明式的阶乘可能看起来像“命令式”的,但它的结构更像声明式的。

命令式阶乘使用可变值、循环计数器和结果来累加计算后的结果。这个方法显式地实现了特定的算法。不像声明式版本,这种方法有许多可变步骤,导致它更难理解,也更难避免 bug 。

使用 JavaScript 进行函数式编程 (一)

函数式JavaScript库

有很多函数式库:underscore.js, lodash,Fantasy Land, Functional.js, Bilby.js, fn.js, Wu.js, Lazy.js, Bacon.js, sloth.js, stream.js, Sugar, Folktale, RxJs 等等。

函数式程序员工具包

map(), filter(), 和 reduce()函数 构成了函数式程序员工具包的核心。 纯高阶函数成了函数式方法的主力。事实上,它们是纯函数和高阶函数应该仿效的典型。它们用一个函数作为输入,返回没有副作用的输出。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn