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 相关文章推荐
Jquery显示、隐藏元素以及添加删除样式
Aug 09 Javascript
JS中FRAME的操作问题实例分析
Oct 21 Javascript
判断字符串的长度(优化版)中文占两个字符
Oct 30 Javascript
jquery.map()方法的使用详解
Jul 09 Javascript
详解为Angular.js内置$http服务添加拦截器的方法
Dec 20 Javascript
Bootstrap源码解读排版(1)
Dec 23 Javascript
Bootstrap笔记之缩略图、警告框实例详解
Mar 09 Javascript
微信小程序 wx.request方法的异步封装实例详解
May 18 Javascript
使用JavaScript实现链表的数据结构的代码
Aug 02 Javascript
React中的refs的使用教程
Feb 13 Javascript
JavaScript常用数学函数用法示例
May 14 Javascript
JS自定义右键菜单实现代码解析
Jul 16 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字符串过滤,转换函数代码
2012/05/01 PHP
PHP实现的简单网络硬盘
2015/07/29 PHP
thinkPHP批量删除的实现方法分析
2016/11/09 PHP
PHP 与 UTF-8 的最佳实践详细介绍
2017/01/04 PHP
php获取给定日期相差天数的方法分析
2017/02/20 PHP
PHP生成加减算法方式的验证码实例
2018/03/12 PHP
jQuery Animation实现CSS3动画示例介绍
2013/08/14 Javascript
javascript中传统事件与现代事件
2015/06/23 Javascript
AngularJs Dependency Injection(DI,依赖注入)
2016/09/02 Javascript
移动端脚本框架Hammer.js
2016/12/15 Javascript
JS实现的Unicode编码转换操作示例
2017/04/28 Javascript
node跨域转发 express+http-proxy-middleware的使用
2018/05/31 Javascript
详解webpack编译速度提升之DllPlugin
2019/02/05 Javascript
JavaScript接口实现方法实例分析
2020/05/16 Javascript
python实现DNS正向查询、反向查询的例子
2014/04/25 Python
自己编程中遇到的Python错误和解决方法汇总整理
2015/06/03 Python
Python之web模板应用
2017/12/26 Python
Python实现定时备份mysql数据库并把备份数据库邮件发送
2018/03/08 Python
wx.CheckBox创建复选框控件并响应鼠标点击事件
2018/04/25 Python
Python异常的检测和处理方法
2018/10/26 Python
手把手教你pycharm专业版安装破解教程(linux版)
2019/09/26 Python
pytorch中的自定义反向传播,求导实例
2020/01/06 Python
使用HTML5的表单验证的简单示例
2015/09/09 HTML / CSS
HTML5新增form控件和表单属性实例代码详解
2019/05/15 HTML / CSS
c/c++某大公司的两道笔试题
2014/02/02 面试题
车辆维修工自我评价怎么写
2013/09/20 职场文书
纪念建党演讲稿范文
2014/01/13 职场文书
八项规定整改措施
2014/02/12 职场文书
会计核算科岗位职责
2014/03/19 职场文书
安全生产工作汇报材料
2014/10/28 职场文书
党员承诺书范文2015
2015/04/27 职场文书
缅怀先烈主题班会
2015/08/14 职场文书
小学四年级班主任工作经验交流材料
2015/11/02 职场文书
2016年“我们的节日·端午节”活动总结
2016/04/01 职场文书
个人工作总结怎么写?
2019/04/09 职场文书
解决Navicat for Mysql连接报错1251的问题(连接失败)
2021/05/27 MySQL