函数式编程核心理念是就是范畴论
react和Angular中运用了大量的函数式编程的思维
react中的高阶组件,高阶函数
Angular中的rxjs Observable
注意事项:
1.函数式编程不是用函数(function)来编程
2.不能充满大量的if else
3.给定一个确定的值,一定会有一个确定的输出值(数学中的函数具有可确定性)
专业术语
1.纯函数
对于相同的输入,永远得到相同的输出。而且没有任何可观察的副作用,也不依赖外部的环境变量。
var xs = [1,2,3,4,5,6]
xs.slice(0,3);
xs.slice(0,3);
xs.splice(0,3);
xs.splice(0,3);
array.slice是个纯函数,而splice不是。对于slice,每次输入(0,3)得到的结果是确定,并且不会改变原数组,而splice,输入(0,3),两次执行的结果不一样,所以他不是纯函数
纯函数的优点:可以有效的降低系统的复杂度,并且可以具有可缓存性
loadsh https://lodash.com/
import _ from 'loadsh';
var sin = _.menorize(x=>Math.sin(x));
// 第一次计算可能会慢一些
var a = sin(1);
// 第二次再次计算sin1,因为之前有了缓存。所以,性能极快
var b = sin(1);
2.函数的柯里化
传递给函数的一部分参数来调用它,让他去返回一个函数去处理剩下的参数。
var checkage = age => age>18;
var checkage = min => (age=>(age>min));
var checkage18 = checkage(18);
checkage18(20);
3.函数组合
const compose = (f,g)=>(x=>f(g(x)));
var first = arr=>arr[0];
var reverse = arr=>arr.reverse();
var last = compose(first,reverse);
last([1,2,3,4,5]);
4.Point Free
把一些对象自带的方法转化成纯函数,不要命名一些转瞬即逝的中间变量
5.声明式和命令式代码
命令式
let ceos = [];
for(let i =0;i
声明式
let ceos = company.map(c=>c.ceo);
6.惰性求值,惰性函数
惰性函数
function someOperation(){
someOperation = function(){}
7.高阶函数
把一个函数作为参数,把传入的函数做一个封装,然后返回这个封装函数,达到更高程度的抽象
var add = function(a,b){
return a+b;
}
function math (fun,arr){
return fun(arr[0],arr[1]);
}
math(add,[0,2]);
8.尾调用优化
递归中。函数的最后一次调用,是函数本身
递归需要大量的调用记录,很容易发生栈溢出错误。如果把递归转化成循环,只需要保存一次调用记录就行。(优化)
//不是尾递归,无法优化
function factorial(n){
if(n === 1) return 1;
return n* factorial(n-1);
}
function factorial(n,total){
if(n === 1) return total;
return factorial(n-1,n*total);
}// es6强制使用尾递归
尾递归调用 factorial(n,1);
9.闭包
---------------
函数式编程比较热门的库
lazy;lodash;Rxjs;underscore(源码)
在 Rxjs 中,所有的外部输入(用户输入、网络请求等等)都被视作一种 『事件流』:
用户点击了按钮 --> 网络请求成功 --> 用户键盘输入 --> 某个定时事件发生 —> 这种事件流特别适合处理游戏,上上下下上上下下举个最简单的例子,下面这段代码会监听点击事件,每 2 次点击事件产生一次事件响应:
var clicks = Rx.Observable
.fromEvent(document, 'click')
.bufferCount(2)
.subscribe(x => console.log(x)); // 打印出前2次点击事件
---------------
10.容器,范畴
可以把范畴想象成一个容器,容器里面有值 和 值的变形关系
11.错误处理
try catch throw 不是纯函数
Maybe Either
12.IO
13.Monad