<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>函数式编程</title> </head> <body> <h1>js权威指南</h1> <p>第八章函数__函数式编程示例代码学习</p> <script> //8.8.1使用数组处理函数 //计算数组元素的平均值和标准差 //非函数式编程 function fn1(){ var data=[1,1,3,5,5]; var total=0; for(var i=0;i<data.length;i++){ total+=data[i]; } var mean=total/data.length;//平均数 console.log(mean);//=>3 //标准差是反映一组数据离散程度最常用的一种量化形式,是表示精确度的重要指标。 //所有数减去其平均值的平方和,所得结果除以该组数之个数(或个数减一,即变异数),再把所得值开根号,所得之数就是这组数据的标准差。 var t=0; for(var i=0;i<data.length;i++){ var deviation=data[i]-mean; t+=deviation*deviation; } var stddev=Math.sqrt(t/(data.length-1));//标准差 console.log(stddev)//=>2 } //fn1(); //使用数组方法map()和reduce()计算数组元素的平均值和标准差 function fn2(){ var data=[1,1,3,5,5]; var sum=function(x,y){return x+y}; var square=function(x){return x*x}; //reduce() 使用指定的函数(称为化简函数),将数组元素进行组合,合成单个值返回。 var mean=data.reduce(sum)/data.length; console.log(mean);//=>3 //map() 从头到尾遍历数组,为每个元素调用指定的函数,指定函数的返回值(必须)组成新的数组。 var deviationArr=data.map(function(x){return mean-x}); var stddev=Math.sqrt(deviationArr.map(square).reduce(sum)/(data.length-1)); console.log(stddev)//=>2 } //fn2(); //8.8.2 高级函数 function fn3(){ //高阶函数not()返回一个新的函数odd,odd将它的实参传入f(even),odd再返回f(even)的返回值的逻辑非。 function not(f){ return function(){//返回一个新函数 //apply() 允许显示指定调用所需的this值,即,任何函数可以作为任何对象的方法来调用,哪怕这个函数不是这个对象的方法。 //apply()方法要求以数组的形式传入参数。 var result= f.apply(this,arguments);//调用f() return !result;//对结果求反 } } var even=function(x){//判断是否为偶数 return x%2 === 0; }; var odd=not(even);//判断是否是奇数 var arr=[1,1,3,5,5]; console.log(arr.every(odd));//true } //fn3(); //例2 //自定义数组 map() 方法 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++){ //undo:不明白这里为啥需要判断 i in a if(i in a){ //call()方法允许显示指定调用所需的this值,即,任何函数可以作为任何对象的方法来调用,哪怕这个函数不是这个对象的方法。 //call()方法使用它自有的实参列表作为函数的实参 results[i]= f.call(null,a[i],i,a) } } return results; }; function fn4(){ //mapper()产生一个新函数,新函数将一个数组映射到另一个使用这个函数的数组上。 function mapper(f){ return function(a){ return map(a,f); }; } var increment=function(x){return x+1;}; var incrementer=mapper(increment); console.log(incrementer([1,2,3]));//=>[2,3,4] } //fn4(); //8.8.3不完全函数 //不完全函数是一种函数变换技巧,即把一次完整的函数调用拆分成多次函数调用,每次传入的实参都是完整实参的一部分,每个拆分开的函数叫做不完全函数,每次函数调用叫做不完全调用。 function fn5(){ //实现一个工具函数将类数组对象或对象转为真正的数组 function array(a,n){ //slice() 返回指定数组的一个片段或子数组。含头不含尾,end 可为负。end 省略截取到末尾。 return Array.prototype.slice.call(a,n || 0); } function partialLeft(f){ var args=arguments; return function(){ var a=array(args,1);//开始处理外部第一个args a= a.concat(array(arguments));//然后增加所有的内部实参 return f.apply(this,a);//然后基于这个实参列表调用f() } } var f=function(x,y,z){return x*(y-z);}; console.log(partialLeft(f,2)(3,4));//=>2*(3-4)=-2 } //fn5(); //8.8.4记忆 //memorize()接收一个函数作为实参,并返回带有记忆能力的函数。 function memorize(f){ var cache={};//将值保存在闭包里 return function(){ //将实参转换为字符串,并将其用做缓存的键 //join() 将数组中所有元素转为字符串并按指定的分隔符(默认逗号)连接在一起,返回最后生成的字符串。 var key=arguments.length + Array.prototype.join.call(arguments,","); if(key in cache){ return cache[key]; }else{ return cache[key] = f.apply(this,arguments) } }; } function fn6(){ //定义一个阶乘函数,将上次的计算结果缓存。 //注意:当我们写一个递归函数时,往往需要实现记忆功能。我们更希望调用实现了记忆功能的递归函数,而不是原递归函数。 var factorial=memorize(function(n){ return (n <= 1) ? 1 : n * factorial(n-1); }); console.log(factorial(5));//=>5*4*3*2*1=120 } fn6(); </script> </body> </html>
js权威指南_第八章函数_函数式编程示例代码学习
猜你喜欢
转载自blog.csdn.net/Irene1991/article/details/105866140
今日推荐
周排行