「这是我参与2022首次更文挑战的第38天,活动详情查看:2022首次更文挑战」
天天念叨要回归函数式编程,今天就来看看它的一些基础概念。
函数式编程是一种编程方式,一种思想、规范。 简单说就是以函数为主, 就像vue里面,可能就一两行代码却还要封装一个函数,这就是函数式编程范式,主要作用就是给这段代码赋予了语义(函数名)。
因为在js中,函数可作为参数,所以可以使用函数式编程。下面看几个函数式编程相关的概念
纯函数
简单的说就是一个参数对应一个返回值。就是我们数学里的函数概念,一个变量必定对应一个因变量 y = f(x) 。
不管在任何情况下调用纯函数,只要入参一样,其返回值就相同。 可以说纯函数就是一个从参数到返回值的映射。
违背这一点的就不是纯函数。
比如典型的斐波那契就是一个纯函数。
如果我们稍作修改,它就不是一个纯函数了。
这个返回值就依赖外部变量 a了, 同样的入参,不同的a可能会是不同的结果。
作用 纯函数的只要参数确定,返回值就确定,因此具有高可复用性,因为不受外界影响, 同时其返回值更具有可推测性,利于ts的类型推断。
高阶函数
高阶函数,还是先用数学的复合函数来理解, y = f(f1(x))。 就是一层套一层。
不过,这里的嵌套是指函数作用域的嵌套, 使用函数作为参数或者返回值的函数都是高阶函数。 还是斐波那契,递归就是典型的高阶函数,使用回调函数的也是,例如我们的数组方法foreach、map、find等等。
高阶函数的作用
1. 抽象
抽象就是不具体, 看看我们的回调函数。我们只知道要在将来的某个时候调用一个函数,但是我们在定义函数的时候并不清楚。 就如同,你和同学约好了周末去玩,但是玩什么不确定,玩就对了。就是这种抽象,抽象就意味着不需要硬性规定。 这个还是用数组方法来理解。
2. 缓存
缓存就是利用闭包的特性,加上我们纯函数的确定性,同一个参数却有不同的返回值,那就没得缓存了。 我们仍然把之前的斐波那契稍加改造一下。 目的达到了不过这个性能还是有问题。 也有人叫他惰性函数,计算过的就不想再次计算了,直接拿之前的成果出来应付,就很懒。 写过的代码就可以复制粘贴了。
命令式 更注重如何去做注重过程,声明式则更强调做什么,注重结果。 就像我们写for循环,这就是命令式,用foreach就是声明式,通过高阶函数抽象过程(循环每一步的内容),直接关注做什么(循环)
柯理化
柯理化就是把多元函数转为多阶一元函数。 好像没啥用啊,没事找事。本来一个函数就解决,非得多嵌套一层,不浪费执行栈吗?下面就看看他的作用,或者说这么写的目的。
通用的写法,就是不断地累积参数,直到参数数目与原函数相同,就调用原函数。
柯理化的作用
- 复用参数
就比如说我们前面的加法函数, 我可能要计算
plus(10, 2);plus(10, 5)
,这两个计算的第一个参数都相同,就是第二个参数不同,后面可能还有类似的计算,我能不能把第一个参数固定了,后面只传第二个参数,这就可以用柯理化解决。let plus10 = plus2(10); plus10(2);plus10(5)
,这样我们解决了参数复用问题。 因为我们把函数调用强行多分了几步,有几个参数就至少几步。
我之前是把这个理解为函数工厂的,就是返回一类函数,自定义某些关键因子。就比如,前面的加法函数,就定义一个返回加基准值的函数。
- 延迟执行
延迟执行,还是利用柯理化的强拆, 有时候并不一定上面那样的,就是把一个函数执行分成多步, 我可能暂时只需要执行第一步,第二步等某个时候再执行。 函数的bind方法也是柯理化的体现。
函数式编程除了上面那些基础概念,还有组合 管道 函子等,虽然我用过,但是现在还不是很明白,等搞明白了,再续写一波。