javascript是一门多范式(multi-paradigm)的编程语言,它即支持命令式(imperative)/面向过程(procedural)编程,也支持面向对象编程(oop object-Oriented Programming),还支持函数式编程(functional programming).
常见的三种编程范式javascript
1 命令式 c
2 函数式 lisp
3 面向对象 java c++java
咱们先来看下命令式是怎么求一个数组的最大值的
var arr = [1,2,3,4,5,6];
var len = arr.length;
var max = arr[0];
for(var i=0;i<len;i++){
if(arr[i] > max){c++
max = arr[i];
}
}
这就是命令式编程 for循环的形式 7行代码,多了几个全局变量编程
咱们尝试改造下,采用排序的方式数组
var max = arr.sort((a, b) => b - a)[0]; 缓存
确实简洁很多。但有一个负做用,把arr的内容给修改了。这不是一个纯函数该干的事。咱们再优化下数据结构
var sum = arr.reduce(function (a, b) {
return a > b?a:b
});
再变成箭头函数
var sum = arr.reduce((a,b) =>{return a>b?a:b;});
没有多余的全局变量,也没有修改调动的数组。这就是一个函数式编程的一个典型例子。app
近年来。函数式编程愈来愈多获得开发这的青睐,函数式编程是一种强调减小对程序外部状态产生改变的方式。所以它鼓励使用不可变数据结构合纯函数编程,鼓励使用声明式编程而非命令式编程,经过简而已懂的函数命令方式,描述目标性质,获得想要的结果,而非流程式,指令式。函数式编程即不依赖外部状态,也不修改外部状态,能够使代码更容易理解,维护,测试,不易出错。编程语言
函数式编程有5大特性函数式编程
纯函数是一种函数,它不改变程序的外部状态,也不会形成数据可变性,纯函数的输出彻底依赖于它的输入值,对于相同的输入,永远返回相同的输出。
好比 slice 和 splice,这两个函数的做用并没有二致——可是注意,它们各自的方式却大不一样,但无论怎么说做用仍是同样的。咱们说 slice 符合纯函数的定义是由于对相同的输入它保证能返回相同的输出。而 splice 却会嚼烂调用它的那个数组,而后再吐出来;这就会产生可观察到的反作用,即这个数组永久地改变了。
var xs = [1,2,3,4,5]; // 纯的 xs.slice(0,3); //=> [1,2,3] xs.slice(0,3); //=> [1,2,3] xs.slice(0,3); //=> [1,2,3] // 不纯的 xs.splice(0,3); //=> [1,2,3] xs.splice(0,3); //=> [4,5] xs.splice(0,3); //=> []
纯函数的好处很是的多。这让单元测试,可缓存性,可移植行,文档化,成为很轻松的事。
不可变数据指一个值,一旦被建立,就永远不会发生改变。在js基本数据类型中,数字,字符串和布尔值是永远不变的。但对象和数组的数据结构在某些操做下是可变的。
var x = [1,2] console.log(x) x.push(3); console.log(x) //数组可变,x被改变了 var x = [1,2],y; console.log(x); y = x.concat([3]); console.log(x) //数组不可变
函数反作用是指当调用函数是,除了返回函数值以外,还对该函数外部的状态产生了改变。函数反作用会给程序带来没必要要的麻烦,给程序带来潜在的错误,而且下降程序的可读性。
var x = 1 var fn = function(y){ x = x+y } fn(2) console.log(x)
函数组合就是组合两到多个函数来生成一个新函数的过程。将函数组合在一块儿,就像将一连串管道扣合在一块儿,让数据流过同样。
简而言之,函数 f 和 g 的组合能够被定义为 f(g(x)),从内到外(从右到左)求值。也就是说,求值顺序是:
例如underscore里面compose函数的实现
function compose() { var args = arguments; var start = args.length - 1; return function() { var i = start; var result = args[start].apply(this, arguments); while (i--) result = args[i].call(this, result); return result; }; };
compose(d, c, b, a)
函数柯里化指把接受多个参数的多参函数转换成每次只接受一个参数的单参函数,而且返回能够接受余下参数的新函数,最大的特色是延迟执行,增长了函数的适用性。
上述几个点均可以分开单独的来阐述,网上也有特别多的介绍。后续再一一展开来描述下上面的特性
正在努力的改变本身的编码习惯朝着函数式编程努力着