浅析函数式编程

一:什么是函数式编程

函数式编程(英语:functional programming)或称函数程序设计、泛函编程,是一种编程范式,它将计算机运算视为函数运算,并且避免使用程序状态以及易变对象。即对过程进行抽象,将数据以输入输出流的方式封装进过程内部,从而也降低系统的耦合度。

二:为什么要使用函数式编程

函数式编程与面向对象式编程是同一级概念:函数不是function,讲的是一种编程的思想,相对于面向对象,函数式编程是将事物之间的关系抽象到程序世界
函数式编程不会保留计算中的中间结果,所以变量是不可变的(无状态的)
我们可以把一个函数的执行结果交给另一个函数去处理

/非函数式编程
let num1 = 2;
let num2 = 5;
let sum = num1 + num2;
console.log(sum)

//函数式编程
function add (n1, n2){
  return n1 + n2;
}
let sum = add(2 , 3)
console.log(sum)

函数式编程能够更大程度上复用代码,减少冗余
vue3.0重构运用了大量的函数式编程,react也是如此。

三:函数式编程常用的术语
1、Arity:指函数的参数数量

这是代表一个函数的参数数量,从1 2 3数量的单词一次是unary(一元)、binary(二元) ternary(三元)等等,这些单词都有后缀:"-ary"或"-ity",如果一个函数带有两个参数称为binary函数,一个函数带许多可变参数称为"variadic,",而一个binary函数有且只有两个参数。

const sum = (a, b) => a + b; const arity = sum.length; console.log(arity);
// => 2 //sum的参数arity数量是2
2、高阶函数(HOF:Higher-Order Function)

一个函数将函数作为参数,并且/或者返回也是一个函数,这个函数称为高阶函数:

const filter = (pred, xs) => {
const result = [];
for (var idx = 0; idx < xs.length; idx += 1) {
   if (pred(xs[idx])) {
     result.push(xs[idx]);
   }
 }
     return result;
 };

该函数调用:
filter(is(Number), [0, '1', 2, null]); // => [0, 2]
其中is函数是作为filter的参数函数
3、偏函数应用(Partial)

对一个有多个参数的函数,如果我们从其只获得更少参数的函数,这个过程处理称为partial应用。

 let sum = (a, b) => a + b;
// partially只应用了 `a`参数为 `40` ,'b'参数没有使用
let partial = sum.bind(null, 40);
// 现在使用了`b` 参数
partial(2); //=> 42

注意,Javascript的bind call和apply都是类似,其第一个参数被绑定的函数,这里设为null,没有使用,后面开始按照函数的参数固定顺序对应了。

4、Currying柯里化

转换一个带有多个参数的函数到同样的函数但是只带有一个参数了,不要和partial应用混淆,后者能产生多于一个参数的函数。

// 非柯里化,我们想要实现一个把参数相加,返回和的函数
function adder(a, b) {
   return a + b;
}
adder(4,6);
// 结果为:10
用柯里化实现:
var adder = function() {
   return function(y) {
   return n + y; // y为6 返回 4+6
  }
}
adder(4)(6) // 10

从上面可以看到,本来adder是传2个参数adder(4, 6),柯里化的方式后,就成为了adder(4)(6),即每次接受一个参数并放回一个函数,然后链式的执行。。。

5、纯函数(Punty)

对于相同的输入,永远得到相同的输出,不依赖,不修改其作用域之外变量的函数。比如JS的数组的slice方法,不管你执行了多少遍,最后输出这个数组都是不变的,其实也就是没有改变原数组。。

比如:var arr=[1,2,3,4,5]
//数组的slice方法,不管你执行了多少遍,最后输出这个数组都是不变的
arr.slice(0,3);
arr.slice(0,3);

// 数组的splice方法会改变原数组,所以相同的输入得不到相同的输出。
arr.splice(0, 3); // [1, 2, 3]
arr.splice(0, 3); // [4, 5]

所以对于slice方法来说是纯函数,对于splice来说是非纯函数。

6、幂等()

同一个函数使用相同的参数嵌套执行多次的结果与执行一次的结果相同。

f(…f(f(x))…)=f(x)
Math.abs(Math.abs(10)) sort(sort(sort([2,1])))
7、副作用(Side effects)

一个函数或表达式如果出现下面情况被认为有副作用:除了返回一个值,它还修改了内部状态,或者有一个和外部函数有一个能够被观察的交互,所谓能够被观察,也就是能被外界植入改变状态的可能,提供了改变内部状态的可能。一般IO操作是有副作用的。

资料参考:
https://www.jdon.com/idea/js/functional-programming-jargon.html
https://www.cnblogs.com/aademeng/articles/7582010.html

你可能感兴趣的:(浅析函数式编程)