前言:
函数式编程,最早源自20世纪30年代 lambda 演算,即函数分发给函数,用作参数,也可以作为结果由函数返回,更为复杂的函数称为高阶函数,可以处理函数,把函数当作参数返回或者二者兼具。
函数式编程基本概念
函数式编程有几个核心的概念:不可变性、纯函数、数据转换、高阶函数、递归。下面我们来分别说说。
不可变性
显而易见 从字面上就能理解,那么不可变性它的意义体现在什么方面呢?下面我们举一个例子就能使你很好的理解:如果你需要对外公开自己的出生证明,但是想去掉隐私的信息,你有两种选择:拿一只大号马克笔把出生证明上的隐私信息涂掉,或者找一台复印机。复制一份出生证明,然后用大号马克笔涂改副本。你会选择哪种方式,显然后者更好,这样既处理了隐私信息,又保障了原件没有损坏。应用中不可变数据就是这个意思。我们不直接更改原始数据结构,而是创建一份数据结构的副本,所有操作都使用副本。
纯函数
纯函数指基于参数做计算,并返回一个值的函数。纯函数至少接受一个参数,而且始终返回一个值会另一个函数。这种函数没有副作用,不设置全局变量,也不更改应用的状态。纯函数把参数视为不可变数据。纯函数易于测试,不改变外界环境,一切通过参数来获取,编写纯函数的三条规则:
- 函数应该至少接受一个参数
- 函数应该返回一个值或者一个函数
- 函数不应该更改任何参数
数据转换
前面我们讲到数据都是不可变的,信息在一个应用中如何流动呢? 在函数式编程中,数据从一种格式变成另一种格式。我们要做的是使用函数产出转换后的副本。这样的函数减少了的命令式属性,从而能降低复杂度。 你不需要任何框架就可以根据一个数据集产出另一个数据集,JavaScript在语言层面上就内置了完成这项任务所需的工具。若想精通JavaScript函数式编程,必须掌握两个核心函数,即Array.map 和 Array.reduce 。 如果想定义一个函数,创建一个新数组,可以使用Array.filter 如果想要从数组中删除数据可以使用此方法 基于前面我们提到的数据的不可变性所以我们的方法要尽可能的不改变原来的数据结构:所以我们常用到数组中的不改变原数组的方法主要有这几种:
- Array.map(fn);
- Array.filter(fn);
- Array.concat(arr);
- Aarray.join();
- Array.slice();
- Array.some();
- Array.every(); 渲染数据的话常用map, 添加常用concat 删除常用filter 修改常用 map react的官网中有这样一个表格:
如果想把数组转成对象,可以结合Array.map 和 Object.keys 。 Object.keys方法从对象中获取所有的键返回由键构成的数组。 reduce 和 reduceRight 函数可用于把数组转换成任何值,包括数字,字符串,布尔值,对象,甚至函数。
map 和 reduce 是函数式程序员必不可少的重要武器要想成为一名熟练的JavaScript工程师,那就必须掌握这两个函数。 由一个数据集创建另一个数据集是一项必备技能,任何编程范式都能用到。
高阶函数
高阶函数对函数式编程也是十分重要的。高阶函数是指用于处理其他函数的函数,参数可以是函数,也可以返回函数,或者两者兼具。
第一类高阶函数的接受其他函数作为参数的函数。Array.map 、Array.filter 和 Array.reduce 都接受函数作为参数,因此他们是高阶函数。
返回一个函数的高阶函数有助于我们处理JavaScript复杂的异步操作,创建我们在必要时需要使用或重用的函数。
柯里化(currying)就是需要用到高阶函数的一种函数式技术。
递归
递归模式特别适合在异步操作中使用。递归技术适合在搜索数据结构中使用。你可以递归迭代子文件夹,直到找出包含文件的文件夹为止。也可以递归迭代html dom。直到找到一个没有子节点的元素为止。 递归是一项强大的函数式技术,实现起来是一种享受。