函数式编程范式 - 图2

一、函数式编程的本质以及应用场景

函数式编程是一种编程范式,他指导我们将程序看做一系列函数运算。
编程范式指导并约束了程序员如何抽象现实中问题,同时不同的编程语言也遵循并实现了不同的编程范式。
所以函数式编程本质上就是用函数来抽象问题
函数组合, 函数式更注重What而命令式更注重How
场景:

  • 高阶函数
  • 纯函数
  • 闭包
  • 柯里化
  • 函数组合
  • 管道(Point Free)
  • 函子

    二、如何以函数式编程风格创建应用程序

    1、高阶函数

2、纯函数

js很多内置函数举例
slice 就是纯函数 不会改变原数组,有对应的结果, splice不是纯函数,每次返回值不固定,原数组改的面目全非
纯函数相比非纯函数来说,具有更好的可测试性、可缓存性、可移植
非纯函数变成纯函数的基本手段是不要依赖系统状态
**

3、闭包

闭包函数的概念:有权访问内部函数的私有变量
闭包作用一般是保护和保存, 保护函数内部变量,不被全局变量污染冲突,保存内部变量不被销毁
就保护而言 函数内部声明一个变量, 无论外部变量如何修改都不会影响内部变量,就可以称作闭包

  1. var a = 10
  2. function test(){
  3. var a = 5
  4. console.log(a)
  5. }
  6. a = 20
  7. test()
  8. // 打印 a = 5

实际中更多的是利用闭包的保存作用
比如下面的例子

  1. function test(){
  2. var x = 10
  3. return function(y){
  4. return x + y
  5. }
  6. }
  7. let a = test()
  8. a(1) // 11
  9. let b = test()
  10. b(2) // 12

第一次执行test的时候,外部函数执行,销毁,内部函数创建一个堆内存 内存地址指向了 全局变量a , 这个堆内存的作用域内x也被保存了下来
闭包的好处: 保护保存-> 封装, 自执行函数,维护内部变量,提高执行速度, 可以做缓存
缺点: 滥用闭包消耗内存,方法: 手动将内存地址指向设为空,让垃圾回收机制自动回收

4、柯里化 curry

函数式编程范式 - 图3

低阶函数转化为高阶函数的过程,通过传递不同参数,调用函数返回新函数,对参数进行一定缓存的高效编写函数的方式
例如 编写多次加法的函数

  1. // es5
  2. function add(x){
  3. return function(y){
  4. return x+y
  5. }
  6. }
  7. let increment = add(10)
  8. increment.add(11) // 21
  9. // es6
  10. const add = x => (y => x+y)

5、函数组合

对统一对象进行多次操作,通过从右向左的顺序依次执行 的compose组合方式的函数
如 对字符串进行大写添加!的操作传统写法是

  1. function toUpperCase(str){
  2. return str.toUpperCase()
  3. }
  4. function exclaim(str){
  5. return str+'!'
  6. }
  7. var shout = function(x){
  8. return exclaim(toUpperCase(x));
  9. };
  10. shout('hello world') //=> "HELLO WORLD!"

像上面书写的函数一多,写法嵌套就会变深不直观,我们可以用函数组合

  1. const componse = (...args) => x => args.reduceRight((value,item)=> item(value) , x)
  2. function toUpperCase(str){
  3. return str.toUpperCase()
  4. }
  5. function exclaim(str){
  6. return str+'!'
  7. }
  8. componse(toUpperCase,exclaim)('hello world') //=> "HELLO WORLD!"

可见函数组合也对参数进行了柯里化处理,前面的参数就是所有函数的数组,第二个参数是最后的操作的对象,返回每个函数执行后的最终结果

三、用简单的代码构建复杂的应用程序


四、纯函数的定义以及为什么使用纯函数

五、为什么消除和控制副作用如此重要

六、柯里化、compose、高阶函数的优点

七、不可变的数据结构

八、常见库(Lodash、Ramda.js)