js 函数式编程学习笔记


Posted in Javascript onMarch 25, 2017

(1)平常写的函数大多是接受值,合并值,返回值,比如经常写的for循环:

function printArray(array){
  for(var i=0;i<array.length;i++){
     print(array[i]); 
  }   
}

但是如果我们想做print之外的事情呢?怎么办?再写一个相似的,未免显得浪费,我们可以这样

function forEach(array,action){
  for(var i=0;i<array.length;i++){
    action(array[i]); 
  } 
}
forEach(["a","b","c"],print);

通过利用匿名函数,在编写for循环之类的可以省去很多无用的细节:

function sum(numbers){
  var total = 0;
  forEach(numbers,function(number){
     total+=number;
  })   
  return total;  
}

上面的例子中是“遍历数组”,并使其抽象化,函数作为函数参数传入....

(2)另一种是传入函数参数,返回函数,可以在“高阶函数”中传入arguments

function negate(func){
  return function(x){
    return !func(x); 
  }
}
var isNotNaN = negate(isNaN);
isNotNaN(NaN);

如果想要反转的函数接受参数大于1个,怎么办?? 很简单,借助apply方法,上下文传入NULL

传说中的组合模式:
function compose(f1,f2){
   return function(){
      return f1(f2.apply(null,arguments));
   };
}

var isNotNaN = compose(op["!"],isNaN);
isNotNaN(5); =>true

间接函数调用,如果运行次数较多还是不要用的好..

(3)sum函数实际上是算法的一个变体,该算法通常称为规约

function reduce(combine,base,array){
  forEach(array,function(element){
    base = combine(base,element);
  });
}

function add(a,b){
 return a+b;
}

reduce(add,0,array);

(4)另外一个与数组相关的有用的基本算法称为“映射”。它能够遍历数组

function map(func,array){
  var result = [];
  forEach(array,function(element){
    result.push(func(element));
  });
  return result;
}

map(Math.round,[0.01,2,9,Math.PI]);

(5)下面这段代码,可以研究下它的工作原理

function splitParagraph(text){
  function split(pos){
     if(pos == text.length) return [];
     else if(text.charAt(pos) == "*"){
         var end = findClosing(“*”,pos+1);
         frag = {type:“emphasized”,content:text.slice(pos+1,end)};
         return [frag].concat(split(end+1));  //回调
     } else if(text.charAt(pos) == "{"){
         var end = findClosing(“{”,pos+1);
         frag = {type:“emphasized”,content:text.slice(pos+1,end)};
         return [frag].concat(split(end+1));  //回调
     } else{
        var end = findOpeningOrEnd(pos),
           frag = {type:"normal",content:text.splice(pos+1,end)};
           return [frag].concat(split(end));

     }
  }
  function findClosing(character,from){
     var end = text.indexOf(character,from);
     if(end == -1) throw new Error("Missing closing ' "+character+"'");
     return end;
  }
  function findOpeningOrEnd(from){
     function indexOrEnd(character){
        var index = text.indexOf(character,from);
        return index = -1?text.length:index;
     }
     return Math.min(indexOrEnd("*"),indexOrEnd("{"));
  }
  
  return split(0);  
}

这种函数的编程风格很独特,使用递归而不是循环,其实递归效率是比较低的,改进如下:

function split(){
   var pos = 0,fragments = [];
   while(pop<text.lenght){
      if(text.charAt(pos) == "*"){
         var end = findClosing("*",pos+1);
         fragments.push({type:"emphasized",content:text.slice(pos+1,end)});
         pos = end+1;
      }else if(text.charAt(pos) == "{"){
         var end = findClosing("}",pos+1);
         fragments.push({type:"footnote",content:text.slice(pos+1,end)});
      }
      else{
         var end = findOpeningOrEnd(pos);
         fragments.push({type:“footnote”,content:text.slice(pos,end)});
         pos = end;
      }

   }
   return fragments;
}

(6)分布应用模式

function partial(func){
   var knownArgs = arguments;
   return function(){
      var realArgs = [];
      for(var i=1;i<knownArgs.length;i++){ //from 1
        realArgs.push(knowArgs[i]);
      }
      for(var i=0;i<arguments.length;i++){
        realArgs.push(arguments[i]); 
      }
      return func.apply(null,realArgs);
   }
}

map(partial(op["+"],1),[0,2,4,6,8,10]); // op["+"] swithcase 的一个function
Javascript 相关文章推荐
javascript之AJAX框架使用说明
Apr 24 Javascript
基于jQuery的history历史记录插件
Dec 11 Javascript
基于JavaScript实现继承机制之调用call()与apply()的方法详解
May 07 Javascript
用jquery写的一个万年历(自写)
Jan 20 Javascript
jQuery焦点图轮播插件KinSlideshow用法分析
Jun 08 Javascript
JQuery组件基于Bootstrap的DropDownList(完整版)
Jul 05 Javascript
完美实现八种js焦点轮播图(上篇)
Jul 18 Javascript
Web安全测试之XSS实例讲解
Aug 15 Javascript
jquery ui sortable拖拽后保存位置
Apr 27 jQuery
基于游标的分页接口实现代码示例
Nov 12 Javascript
JavaScript实现滑动门效果
Jan 18 Javascript
vue v-model的用法解析
Oct 19 Javascript
CodeMirror js代码加亮使用总结
Mar 25 #Javascript
js 去掉字符串前后空格实现代码集合
Mar 25 #Javascript
在js中做数字字符串补0(js补零)
Mar 25 #Javascript
JavaScript 字符串数字左补位,右补位,取固定长度,截位扩展函数代码
Mar 25 #Javascript
JS去掉字符串前后空格或去掉所有空格的用法
Mar 25 #Javascript
javascript作用域链与执行环境详解
Mar 25 #Javascript
vue中用动态组件实现选项卡切换效果
Mar 25 #Javascript
You might like
深入PHP数据缓存的使用说明
2013/05/10 PHP
PHP实现带重试功能的curl连接示例
2016/07/28 PHP
Laravel6.2中用于用户登录的新密码确认流程详解
2019/10/16 PHP
如何在PHP中使用数组
2020/06/09 PHP
刷新页面实现方式总结(HTML,ASP,JS)
2008/11/13 Javascript
12款经典的白富美型—jquery图片轮播插件—前端开发必备
2013/01/08 Javascript
jQuery设置与获取HTML,文本和值的简单实例
2014/02/26 Javascript
用JavaScript实现一个代码简洁、逻辑不复杂的多级树
2014/05/23 Javascript
jQuery实现Twitter的自动文字补齐特效
2014/11/28 Javascript
js获取json元素数量的方法
2015/01/27 Javascript
浅析jQuery事件之on()方法绑定多个选择器,多个事件
2016/04/27 Javascript
Javascript实现图片加载从模糊到清晰显示的方法
2016/06/21 Javascript
JCrop+ajaxUpload 图像切割上传的实例代码
2016/07/20 Javascript
Angular2.0/4.0 使用Echarts图表的示例代码
2017/12/07 Javascript
关于JSON解析的实现过程解析
2019/10/08 Javascript
微信小程序自定义弹出模态框禁止底部滚动功能
2020/03/09 Javascript
详解Vue Cli浏览器兼容性实践
2020/06/08 Javascript
JS highcharts动态柱状图原理及实现
2020/10/16 Javascript
[00:29]2019完美世界全国高校联赛(秋季赛)总决赛海口落幕
2019/12/10 DOTA
浅谈关于Python3中venv虚拟环境
2018/08/01 Python
Django封装交互接口代码
2020/07/12 Python
高中自我鉴定范文
2013/11/03 职场文书
名人演讲稿范文
2013/12/28 职场文书
国际贸易专业个人职业生涯规划
2014/02/15 职场文书
2014信息公开实施方案
2014/02/22 职场文书
大一工商管理职业生涯规划:有梦最美,行动相随
2014/09/18 职场文书
2014年学校工作总结
2014/11/20 职场文书
2014年后勤管理工作总结
2014/12/01 职场文书
保送生自荐信范文
2015/03/26 职场文书
2015初中政教处工作总结
2015/07/21 职场文书
受欢迎的自荐信,就这么写!
2019/04/19 职场文书
Go各时间字符串使用解析
2021/04/02 Golang
MySQL pt-slave-restart工具的使用简介
2021/04/07 MySQL
Python3 多线程(连接池)操作MySQL插入数据
2021/06/09 Python
总结一下关于在Java8中使用stream流踩过的一些坑
2021/06/24 Java/Android
面试中老生常谈的MySQL问答集锦夯实基础
2022/03/13 MySQL