Home > Article > Web Front-end > JavaScript functional programming example analysis_javascript skills
The examples in this article describe javascript functional programming. Share it with everyone for your reference. The specific analysis is as follows:
JS, like other dynamic languages, can write high-order functions. The so-called high-order functions are functions that can operate functions. Because in js a function is a complete object and belongs to the first class of citizens, which provides the prerequisites for functional programming.
The following is an example code from a js tutorial. Its function is to calculate the average and standard deviation of array elements. First, let’s list a way of writing non-functional programming:
var data = [1,1,3,5,5]; var total = 0; for(var i = 0;i < data.length;i++) total += data[i]; var mean = tatal/data.length; //平均数为3 //计算标准差 total = 0; for(var i = 0;i < data.length;i++){ var deviation = data[i] - mean; tatal += deviation * deviation; } var stddev = Math,.sqrt(total/(data.length-1));//标准差为2
In order to use functional programming, we pre-define some helper functions:
//将类数组对象转换为真正的数组 function array(a,n){ return Array.prototype.slice.call(a,n||0); } //将函数实参传递至左侧 function partial_left(f){ var args = arguments; return function(){ var a = array(args,1); a = a.concat(array(arguments)); return f.apply(this,a); }; } //将函数的实参传递至右侧 function partial_right(f){ var args = arguments; return function(){ var a = array(arguments); a = a.concat(array(args,1)); return f.apply(this,a); }; } //该函数实参被用做模版, //实参列表中的undefined值会被实际实参值填充。 function partial(f){ var args = arguments; return function(){ var a = array(args,1); var i = 0,j = 0; for(;i<a.length;i++) if(a[i] === undefined) a[i] = arguments[j++]; a = a.concat(array(arguments,j)); return f.apply(this,a); }; } //返回一个函数类似于f(g()) function compose(f,g){ return function(){ return f.call(this,g.apply(this,arguments)); }; }
Below we give the js code completely using functional programming:
var data = [1,1,3,5,5]; var sum = function(x,y){return x+y;}; var product = function(x,y){return x*y;}; var neg = partial(product,-1); var square = partial(Math.pow,undefined,2); var sqrt = partial(Math.pow,undefined,0.5); var reciprocal = partial(Math.pow,undefined,-1); //好吧,高潮来鸟 :) var mean = product(reduce(data,sum),reciprocal(data.length)); var stddev = sqrt(product(reduce(map(data,compose(square,partial(sum,neg(mean)))),sum),reciprocal(sum(data.length,-1))));
Except for the reduce and map functions, other functions are given above. The reduce function is similar to the inject function in ruby:
ary = (1..10).to_a ary.inject(0) {|sum,i|sum + i} //结果为55
js is written as follows:
var ary = [1,2,3,4,5,6,7,8,9,10] ary.reduce(function(sum,i){ return sum + i; },0);
0 is the initial value of sum. If omitted, sum is the value of the first element of the array. It can be omitted here.
The map function is also very simple. It is similar to operating on each element of the array and then returning an array after the operation. Take ruby code as an example. The js code is similar to this:
a = (1..3).to_a; #数组[1,2,3] a.map {|x| x*2} #返回新数组[2,4,6]
Let’s analyze that long string of code:)
sum and product define functions for adding and multiplying elements;
neg is also a function equivalent to: product(-1,x), which means negative x value;
The square function is equivalent to: Math.pow(x,2), which calculates the square value of x. Note that the second parameter of partial here is undefined, which means that the formal parameter here will be replaced by the first actual parameter. Fill in; let’s be clear: the square(x) function is equal to Math.pow(x,2).
The sqrt function is similar to square, and its function is equivalent to: Math.pow(x,0.5), which is equivalent to calculating the square root of x.
The last function reciprocal is not difficult. It is equivalent to: Math.pow(x,-1), that is, calculating the negative power of x, which is equivalent to calculating the reciprocal of x.
Here’s how to knead the above functions together :)
Let’s look at the calculation of the average first. It’s very simple: first calculate the sum of the array elements and then multiply it by the reciprocal of the array length, that is, the array sum/array length.
Finally, looking at the seemingly difficult standard deviation, we’d better look from the inside out:
First look at the layer containing neg:
//等价于函数sum(-1 * mean + x) partial(sum,neg(mean)
Look at the compose function below:
//下面在源代码上做了等价替换,可以再次等价于: //square(sum(-1*mean + x)),再次展开(我剥,我剥,我剥洋葱...): //Math.pow(sum(-1*mean + x),2); compose(square,sum(-1*mean + x))
Let’s look at the map function:
//It’s very clear! ? That is, each element in data is an average and then raise the result to the power of 2.
map(data,Math.pow(sum(-1*mean + x),2))
Then look at the reduce function outside the map:
//将前面新数组的每个元素值加起来。 reduce(map(...),sum)
Then take a look at the reciprocal function:
//等价于求(data.length-1)的倒数 reciprocal(sum(data.length,-1))
Look at the outer product function:
//等价于新数组元素的和除以(data.length-1) product(reduce(...),reciprocal(...))
The outermost sqrt means finding the square root of the result of the above division; you can compare it with the previous non-functional programming code, it is the same:) It seems to be a big mess of code that is quite intimidating, but it is difficult after analysis It will reach zero immediately. If you, the reader, say you still don’t understand it in the end, it’s entirely a matter of my cat’s language expression ability, and you’re welcome to ask questions.
The explanation is over, the fight is over, and you’re done.
I hope this article will be helpful to everyone’s JavaScript programming design.