从EcmaScript角度进行功能编程。 纯函数,λ,抗扰度

哈Ha!

今天,我们将开始讨论一个非常重要的主题-函数式编程。 FP在现代Web开发中的重要性很难高估。 任何大型现代项目的体系结构都包括用户定义的功能库,并且在任何级别的面试中,FI都将存在强制性问题。

函数式编程简介


函数式编程(FP)是通过编写一组函数来组织代码的方式。

EcmaScript是一种多范式编程语言,它实现了一种功能范式。 这意味着ES中的函数是数据,可以传递给函数,从函数返回并可以接受函数本身。 即 ES中的函数一流的函数

从此得出以下定义:

功能参数(funarg) -参数值为函数的参数。

高阶函数(FWP,高阶函数,hof)是接受函数作为参数的函数。

具有函数值的函数(函数值函数) -返回函数的函数。

所有这些类型的功能有条件地组合到第一类的功能中,并且根据上述定义,在ES中,所有功能都是第一类的对象。

纯函数-函数式编程的理想选择


纯函数(PF) -始终返回预测结果。
PF特性:

  • PF执行的结果仅取决于传递的参数和实现PF的算法
  • 不要使用全局值
  • 不要修改外部值或传递的参数
  • 不要将数据写入文件,数据库或其他任何地方

一个纯函数的例子:

const add = (x,y) => x+y; 

函数杂质的一个很好的例子是:

 var first; var second; function testFn() { var a = 10; first = function() { return ++a; } second = function() { return --a; } a = 2; first();//3 } testFn(); first();//4 second();//3 

试想一下,为该示例编写测试有多复杂,并且为纯函数简化了多少!

不纯功能的特点是时变的外部状态使代码的维护,理解和测试变得复杂。

相反,纯函数总是可读,可测试的,简化了计算的并行化,并且易于重用。

我想您注意到在纯函数示例中,我切换到了ES6语法。 这是故意进行的。 该函数语法称为“箭头函数”,但实际上它是很久以前发明的数学抽象的实现。 关于它进一步。

Lambda-函数


这就是这种箭头形式的数学和其他编程语言所称的形式。 函数式编程与mat紧密相关。 分析,所以不要惊讶。

Lambda演算一词最早是在1930年代由Alonzo Church引入的。 本质上,lambda演算只不过是描述数学方程式的形式。 更多细节在这里

在ES中,lambda函数通常实现闭包:

 const add = x => y => x + y; 

简短而简洁。 add函数是一个lambda,它接受参数x,将其存储在闭包中并返回一个函数。

与以下代码进行比较:

 funtion add(x) { return function (y) { return x + y; } } 

显然,第一种选择看起来更好。

豁免权


不可变(不可变,抗扰性)是创建后状态无法更改的对象。 对此类对象进行任何修改的结果将始终是新对象,而旧对象将不会更改。

不变性是函数式编程的黄金圣杯。

考虑一个例子:

 const impureAddProp = (key, value, object) => { object[key] = value;//   }; const User= { name: 'Alex' }; impureAddProp ('isAdmin', true, User); 

如您所见,在此示例中,我们通过向User对象添加属性来对其进行了突变。 现在,用户对象是impureAddProp函数和其他会使它变异的函数的一种“共享状态”。 这种方法很难测试,因为 更改与共享状态交互的任何功能时,应始终牢记其他功能中可能存在的错误。

从函数式编程的角度来看,这是正确的:

 const pureAddProp = (key, value, object) => ({ ...object, [key]: value }); const User= { name: 'Alex' }; const Admin= pureAddProp ('isAdmin', true, User); 

因此,User对象将保持不变。 我们正在修改数据的副本,这始终是安全的。

结论


今天,我们研究了几个重要的理论概念。 我们熟悉纯函数,记录函数的lambda形式以及fp中不变性的概念。 但是,本文只是一种介绍。 功能编程的主要思想,技术和“硬性部分”将在以下文章中介绍。

函数式编程是由许多库实现的。 这是lambda,lodash和其他许多东西。 当然,在实际项目中,您将使用它们。 在任何库的内部,仍然会有相同的本机javascript,因此在以下文章中,我们将分析FP,并在本机JS上实现其所有概念。

后记


开始写文章时,我想到了以下计划:

  • 撰写有趣的英语文章的翻译
  • 突出显示JS中的几个相关领域(关键概念,根据EcmaScript规范,模式,功能编程的OOP)。

迄今为止,已经写了三个方面的头条:

  1. this和EcmaScript中的ScopeChain-在这里,我描述了规范的关键概念,例如执行上下文,this关键字和ScopeChain上下文属性(作用域链)。 在这个方向的框架内,我有关词法环境和闭包的文章今天已按字面意义发表。
  2. EcmaScript对OOP的一般理论的看法 -这里描述了静态类输入和动态原型组织之间的区别,分解了委托模型和Duck类型
  3. 现代JavaScript中的优雅模式(Bill Sourour编译系列在该周期中) -这是两种在某些情况下有用的模式。 我在模式方面的方法非常简单:最好了解尽可能多的模式,因为 迟早派上用场

现在轮到函数式编程了。 将来,我将在所有这些领域的后续文章中写文章。 例如,以下文章将介绍OOP的关键概念:封装,抽象,杂质(和笔触),接口等。...我还打算讨论如何在幕后实现ES中的OOP。 关于[[Prototype]],[[Class]]的属性等等。 讨论v8如何创建实体以及类,函数的实例。

评论中提出了很多问题,所以我想解释一下我为文章设定的目标。 我不写教程也不审查文档。 我认为这没有任何意义。 我不建议您使用某些工具或模式,它们的选择完全取决于您。

在文章中,我要么回顾这些概念,告诉它们如何在幕后安排(我认为,这可以增进对我们所写内容的理解,以及我们为什么以这种方式进行书写),或者我在谈论一些开阔视野的事情。 我认为这非常重要。 看一下Yandex或Edadil之类的公司,他们不断谈论某种新颖的想法。 这些都是react中的位图,那么vue应用程序几乎完全在es6类上。 大多数Web开发人员永远都不会想到这样的事情。 这需要广阔的前景。

我本人就是以这种方式研究和研究网络的 阅读完教程或扩展坞后,我将尝试了解所描述的工具如何在后台运行,以了解其内部机制。

直到以后的文章,朋友们!

Source: https://habr.com/ru/post/zh-CN474702/


All Articles