函数式编程,应该是非典型的面向对象语言里面都曾经探讨过的一种编程范式吧,大约今年4月份因为工作需要去看react文档时了解到react本身的函数式编程的思想,再到redux使用的建议“不可变数据”时,觉得react真的是JavaScript函数式编程的一种典型实现:不可变数据、纯函数、使用高阶函数、必要时使用柯里化(currying)来优化性能等等都是在践行函数式编程的精髓。
一、概述
函数式编程在维基百科里面的定义是:
In computer science, functional programming is a programming paradigm—a style of building the structure and elements of computer programs—that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data. It is a declarative programming paradigm, which means programming is done with expressions or declarations instead of statements.
提炼出重点来就是:更多的使用表达式或声明而不是语句来完成编程;涉及到计算的都按照数学上的思想来:避免状态和数据的可变性。 解释略微枯燥,用通俗一点的话来说就是,按照函数式编程的思想来说,我们应该写的函数叫做:纯函数,这个函数只要是接收一个确切的参数就永远返回一个确切的结果,所有的答案都是一对一的;尽量避免使用语句来实现所有功能,尽量使用变量、函数或其他内建方法来实现需求(也就是例用柯里化的方式来编程)。
1. 避免状态和数据可变性(纯函数)
举个例子来说明会更好一些 首先是非函数式编程的例子
let number = 2
let sum = function(){
number++
}
sum(number)
sum() //3
sum() //4
//每次调用都会得到不同的结果,造成很大不确定性
下一个是函数式编程的例子
let sum = function(x){
return x+1
}
//不依赖于外部的数据,而且也不改变外部数据的值,而是返回一个新的值给你。
2. 函数柯里化
柯里化指的就是传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。
function cal(x){
return function(y){
return x * y
}
}
//调用时
let num1 = cal(2) //此变量返回的是一个函数
num1(3) //6
//如果使用箭头函数直接写的话会更加简洁
这样,在调用时就可以更加方便地根据业务需求来进行调用,也就是我们提到的延迟调用。 事实上柯里化是一种“预加载”函数的方法,通过传递较少的参数,得到一个已经记住了这些参数的新函数,某种意义上讲,这是一种对参数的“缓存”,是一种非常高效的编写函数的方法;像是lodash这种很出名的库也有专门对于柯里化的处理方式(即curry,引入即可)
3. 声明式编程
//命令式
var CEOs = [];
var compainies = [{},{},{}] //里面包含一些已有的对象,此处不举例
for(var i = 0; i < companies.length; i++){
CEOs.push(companies[i].CEO)
}
//声明式
var CEOs = companies.map(c => c.CEO);
函数式编程主要的范式大约就是以上已有的,主要是三个方面,后续我会坚持把这一系列都写完,主要会从这三个特征里的每一个方面进行一定程度的深入。 最后一句,其实这些文章是用来激励自己的,哈哈哈立下过FLAG要每个周出一篇对我来说有质量的文章,只要是我觉得我为了写这篇文章学到了有用的东西,这就值了~