简析JavaScript中的函数式编程(一)

与Lisp,Haskell不同,JavaScript并非函数式编程语言,但在JS之中可以像操控对象一样操控函数,换句话说,可以在JS中应用函数式编程技术
什么是函数式编程?
函数式编程通过使用函数来将值转换成抽象单元,接着用于构建软件系统。
举个很普通且低级的例子:假设有一个数组,数组元素都是数字,我们想要计算它的平均值和标准差,如果使用非函数式编程那么就是这个样子:

var data = [1,2,3,4,5];
var total = 0;
for(var i = 0; i < data.length; i++)
  total += data[i];
var mean = total / data.length;  //平均数为3
total = 0;
for(var i = 0; i < data.length; i++) {
  var deviation = data[i] - mean;
  total += deviation * deviation;
}
var stddev = Math.sqrt(total / (data.length-1));  //标准差为2

采用函数式编程那么就是这个样子(这里会用到数组方法map()和reduce(),ES3未包含这两种方法,所以下面会先进行判断,如果有map()和reduce()就直接使用,否则就自行定义):

var map = Array.prototype.map?function(a, f) { return a.map(f); }
 :function(a, f) {
    var results = [];
    for(var i = 0,len = a.length; i < len; i++) {
        if (i in a)  results[i] = f.call(null,a[i],i,a);
    }
    return results;
};
var reduce = Array.prototype.reduce?function(a,f,initial) {
  if(arguments.length > 2)
      return a.reduce(f, initial);
  else
      return a.reduce(f);
}
: function(a,f,initial) {
  var i = 0, len = a.length,accmulator;
  if(arguments, length > 2)  
      accmulator = initial;
  else{
    if(len == 0)
        throw TypeError();
    while( i < len){
        if(i in a){
          accumulator = a[i++];
          break;
        }
        else
            i++;
      }
      if(i == len) throw TypeError();
    }
    while( i < len) {
         if ( i in a)
              accumulator = f.call(undefined, accumulator,a[i],i,a);
         i++;
    }
    return accumulator;
});
//下面的代码块就是函数式编程
var sum = function(x,y) { return x+y; };
var square = function(x) { return x*x;};
var data = [1,2,3,4,5];
var mean = data.reduce(sum) / data.length;
var deviations = data.map(function(x) { return x-mean;});
var stddev = Math.sqrt(deviations.map(square).reduce(sum) / (data.length - 1));

用严格的函数式编程的方法来解决问题,会将一个问题分成几部分(函数)来解决。如下图:

简析JavaScript中的函数式编程(一)_第1张图片
38AE6BDC-B547-4D22-A6F4-75352DFD4096.png

函数式编程通过“组合”其他函数的方式来构建更大的函数,以实现更抽象的行为如下图:

简析JavaScript中的函数式编程(一)_第2张图片
7F847FBE-FF80-4C90-A433-EA90A9AF32AE.png

最终,一种将函数的部件组成一个完整的系统的方法是取一个值,逐渐的将它“改变”——通过一个原始的或组合的函数——成为另外一个值。

简析JavaScript中的函数式编程(一)_第3张图片
95E3C3D8-1869-47FB-A031-2E5099D83608.png

你可能感兴趣的:(简析JavaScript中的函数式编程(一))