知足如下两点的函数:javascript
叫高阶函数,很显然js中的函数知足高阶函数的条件。java
函数做为参数:git
function pow(x) { return x * x; } const arr = [1, 2, 3]; const res = arr.map(pow);
函数做为返回值:github
function getPrintFn() { function print(msg) { console.log(msg); } return print; }
高阶函数与函数式编程有什么关系?经过上一篇咱们知道函数式编程采用纯函数,那怎么把不纯的函数转化为一个纯函数呢?经过把不纯的操做包装到一个函数中,再返回这个函数(即上面的例子),便可达到目的。编程
只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。
特色:
接收单一参数,将更多的参数经过回调函数来搞定;
返回一个新函数,用于处理全部的想要传入的参数;
须要利用call/apply与arguments对象收集参数;
返回的这个函数正是用来处理收集起来的参数;数组
function add(x, y) { return x + y; } // 柯里化 function add(x) { return function(y) { return x + y; } } const increment = add(1); increment(2); // 3
当咱们谈论纯函数的时候,咱们说它们接受一个输入返回一个输出。curry 函数所作的正是这样:每传递一个参数调用函数,就返回一个新函数处理剩余的参数。这就是一个输入对应一个输出。curry函数适用于如下场景:网络
在函数式编程中,经过将一个个功能单一的纯函数组合起来实现一个复杂的功能,就像乐高拼积木同样,这种称为函数组合(代码组合)。下面看一个例子:app
最佳实践是让组合可重用。异步
咱们知道,函数式编程实质是经过管道把数据在一系列纯函数间传递,可是,控制流(control flow)、异常处理(error handling)、异步操做(asynchronous actions)和状态(state)呢?还有更棘手的反作用(effects)呢?这些问题的解决就要引入函子的概念了。async
咱们首先定义一个容器,用来封装数据
函子封装了数据和对数据的操做,functor 是实现了map函数并遵照一些特定规则的容器类型。
把值装进一个容器,并且只能使用 map 来处理它,这么作的理由究竟是什么呢?
让容器本身去运用函数能给咱们带来什么好处?
Functor 是一个对于函数调用的抽象,咱们赋予容器本身去调用函数的能力。当 map 一个函数时,咱们让容器本身来运行这个函数,这样容器就能够自由地选择什么时候何地如何操做这个函数,以至于拥有惰性求值、错误处理、异步调用等等很是牛掰的特性。
1.Maybe(处理null问题)
2.Either(if…else)
3.IO(IO、网络请求、DOM)
4.Monad(嵌套问题)
一种用来处理null和undefined问题的函子,避免繁琐的手动判空操做
一种用来处理if…else问题的函子
经过返回一个获取数据的函数来延迟IO的反作用,等调用者去执行有反作用的函数,
以保证获取数据过程当中的无反作用特性
monad 是能够变扁(flatten)的实现了of方法的 functor
学习函数式编程,实际上就是学习函子的各类运算。因为能够把运算方法封装在函子里面,因此又衍生出各类不一样类型的函子,有多少种运算,就有多少种函子。函数式编程就变成了运用不一样的函子,解决实际问题。
参考文档
https://github.com/xitu/gold-...
https://llh911001.gitbooks.io...