什么是函数式编程 ?
函数式编程是一种强调以函数使用为主的软件开发风格**,但是它的思考解决问题方式有所变化,使用函数来获得结果并不重要.
函数式编程的目标是使用函数来抽象作用在数据之上的控制流与操作
从而在系统中消除副作用并减少对状态的改变
入门
document.querySelector('#msg').innerHTML = '<h1>hello world</h1>'
这个程序有以下缺点: 代码写死,不能动态的修改内容,与目标dom元素
你或许使用函数封装这段代码
function printMsg = (eleId,format,message)=> {
document.querySelector(`#${eleId}`).innerHTML = `<${format}>${message}</${format}>`
}
这样确实有所改进,但它仍然不是一段重用的代码,假设要将文本写入文件,而并非html。
我需要将他变成如下
var printMsg = run(addToDom('msg'),h1,echo)
printMsg('hello world')
你会发现 printMsg 为run函数的返回值(run返回一个函数),但是addToDom、h1、echo这几个一样是函数。
在后台,run函数基本上是通过将一个函数的返回值作为下一个函数的输入这种方式将各个函数链接起来
这种做法叫做函数式解决方案,事实上,通过比较函数式与非函数式的解决方案,他们在代码风格上存在区别。
再次之前,我们必须了解一下如下概念
- 声明式编程
- 纯函数
- 引用透明
- 不可变性
传统命令式编程
Java,C++和其他大多数结构化语言和面向对象语言都对其提供命令式编程的支持
var array = [0,1,2,3,4,5]
for(let i=0;i<array.length;i++) {
array[i] = Math.pow(array[i],2)
}
console.log(array[i])
命令式编程就是自上而下的告诉计算机应该执行哪个任务。这在我学习java的时候印象深刻。
如果用函数式来解决相同的问题,只需要对应用的某个数组元素上的行为予以关注,将循环部分交给系统去控制。
array.map(item=> {
return Math.pow(item,2)
})
这里用了map方法执行循环
听一听不是人话的描述:声明式编程时将程序的描述和求值分离开来,它关注如何利用各种表达式描述程序逻辑,而不一定指明其控制流与状态的变化。
本章小结:函数式的代码让开发者免于考虑如何妥善管理循环计的问题。代码了越大,,存在的bug就越多。同时,标准的代码循环时很难被复用的东西,除非将其抽象为函数,函数式编程意义在于如何提高代码的无状态性与不变性。
纯函数
要做到上面几点,必须是纯函数。纯函数有以下特点
- 仅取决于提供的输入,不依赖函数作用域外的变量
- 作用不会超出自身作用域,例如修改全局函数,改变引用传递的参数等
任何不符合以上条件的函数,都是不纯的!例如
var counter = 1
function increment() {
return ++counter
}
在这个例子中,counter可以通过一个全局作用域变量window访问到。另外一个常见的副作用就是this,this对于新手来讲,还是挺特别的,但对于我这种麦克雷,他就是弟弟
以下是常见的副作用
- 改变一个全局的变量、属性、或数据结构
- 改变一个函数参数的原始值
- 处理用户输入
- 抛出异常,除非它被当前函数捕获了
- 屏幕打印或记录日志
- 查询html文档、浏览器或cookie或访问数据库
网友评论