lostvita / blog

60 stars 47 forks source link

JavaScript函数式编程 #9

Open lostvita opened 5 years ago

lostvita commented 5 years ago

翻译: 安歌

原文: Functional Programming in JavaScript

什么是函数式编程

其他主流的编程范式

面向过程编程建立在过程调用的概念之上,包含了一系列的待执行的计算步骤。任何给定的过程都可以在程序执行期间被调用,包括其他或自身的程序。主要的面向过程的编程语言有COBOL、BASIC、C、ADA、GO。

面向对象编程建立在对象的概念之上,包含了属性和方法。这种模式更接近函数式编程。主要的面向对象的编程语言有C++、Java、PHP、C#、Python、Ruby、Swift等。

元编程把程序作为它们的数据,这意味着一个程序可以被设计成在运行时读取、生成、分析或转换其他程序,甚至对自己进行修改。

命令式模式 VS 声明式模式

数学函数还是纯函数?

在数学上,函数是一组输入和一组对应输出间的关系,它的特点是每一个输入组合都只有一个确切的输出。

在函数式编程中,这类函数称作纯函数,它只依赖与函数接收到的输入数据,除了返回结果外,不会改变输入的数据。

Math.random()不是纯函数,因为它的每一次调用都可能返回不同的值。

Math.min(1,2)是纯函数,因为对于给定的一组输入它总是返回相同的输出。

为什么要函数式编程

函数式编程的例子

Array 函数

在上面的例子中,我们尝试只过滤出活跃的聚会组织,正如你看见的那样,我们能通过两种不同的方式来达到这个目的。第二种方式是函数式编程,filter()负责“程序如何执行”,我们只关注输入(meetups数组)以及输出(activeMeetupsFP),但在第一种方式中我们还需要关心如何使用for循环进行操作。

类似的,下面数组的其他方法,也有助于我们实现函数式编程并降低代码的复杂性:

函数链

它是一种调用多个方法的调用机制,通过函数返回一个对象的方式使得每一个方法的调用可以链接在一个语句中,而不需要临时变量存储中间结果值。 在上面的代码片段中,考虑到有10%的成员可能是重复的需要被除去,我们打印出所有活跃组织里的成员总和。

支持FP的库

这是一些提供了很多实用函数使得代码更具声明性的第三方库:

副作用

如果一个程序或表达式会修改其作用域之外的程序状态,或者除了返回值之外,对调用它的函数有任何其他可见的干扰,那么我们称其是有副作用的。 这个程序是有副作用的,因为函数scheduleMeetup的实际职责是给meetup对象添加dateplace属性,但它却又修改了isActive的值,而这个属性是被其他函数如publishMeetup所依赖的。作为副作用,publishMeetup得不到期望的输出,因为它的输入在这期间已经发生了改变。在大型程序(真是程序)中,副作用是很难被调试的。

不可变性

为确保函数不会更改原始数据而不是操作后返回数据的新副本,不变形显得尤为重要。

想象一下如果数组和对象在多个函数之间传递,而我们不去维护不变性,那么函数可能无法获取数组和对象的原始副本。

在易变对象和数组上发生错误是很难调试的。

易变性并不是没有用处,但应该在必要的时候才使用。

支持不变性的库

JavaScript默认不提供任何保证对象和数组不可变的限制,这里有一些库可以帮助我们实现不变性:

总结

函数式编程的主要特征就是纯函数、不可变性和无副作用

如果你喜欢这篇推文并觉得有帮助,请帮忙点个赞,谢谢!