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 相关文章推荐
学习YUI.Ext 第三天
Mar 10 Javascript
JavaScript this调用规则说明
Mar 08 Javascript
JQuery FlexiGrid的asp.net完美解决方案 dotNetFlexGrid-.Net原生的异步表格控件
Sep 12 Javascript
基于jquery的网页SELECT下拉框美化代码
Oct 28 Javascript
Extjs4 消息框去掉关闭按钮(类似Ext.Msg.alert)
Apr 02 Javascript
js实现点击后将文字或图片复制到剪贴板的方法
Aug 04 Javascript
Bootstrap每天必学之缩略图与警示窗
Nov 29 Javascript
详解能在多种前端框架下使用的表格控件
Jan 11 Javascript
解决Vue使用mint-ui loadmore实现上拉加载与下拉刷新出现一个页面使用多个上拉加载后冲突问题
Nov 07 Javascript
JavaScript实现二叉树定义、遍历及查找的方法详解
Dec 20 Javascript
微信小程序学习总结(二)样式、属性、模板操作分析
Jun 04 Javascript
javascript实现搜索筛选功能实例代码
Nov 12 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隐藏IP地址后两位显示为星号的方法
2014/11/21 PHP
Web程序工作原理详解
2014/12/25 PHP
PHP+Mysql+jQuery文件下载次数统计实例讲解
2015/10/10 PHP
php实现文件上传及头像预览功能
2017/01/15 PHP
PHP CURL与java http使用方法详解
2018/01/26 PHP
laravel 使用事件系统统计浏览量的实现
2019/10/16 PHP
奇妙的js
2007/09/24 Javascript
Ext 今日学习总结
2010/09/19 Javascript
基于jQuery实现图片的前进与后退功能
2013/04/24 Javascript
用html+css+js实现的一个简单的图片切换特效
2014/05/28 Javascript
javascript学习指南之回调问题
2016/04/23 Javascript
基于JS实现移动端向左滑动出现删除按钮功能
2017/02/22 Javascript
JavaScript数据结构中串的表示与应用实例
2017/04/12 Javascript
jQuery实现返回顶部按钮和scroll滚动功能[带动画效果]
2017/07/05 jQuery
详解在vue-cli项目中使用mockjs(请求数据删除数据)
2017/10/23 Javascript
解决vue多个路由共用一个页面的问题
2018/03/12 Javascript
详解使用jQuery.i18n.properties实现js国际化
2018/05/04 jQuery
微信小程序获取用户绑定手机号方法示例
2019/07/21 Javascript
基于JS实现table导出Excel并保留样式
2020/05/19 Javascript
如何区分vue中的v-show 与 v-if
2020/09/08 Javascript
Python+Selenium自动化实现分页(pagination)处理
2017/03/31 Python
详解python上传文件和字符到PHP服务器
2017/11/24 Python
python自动化工具之pywinauto实例详解
2019/08/26 Python
python+jinja2实现接口数据批量生成工具
2019/08/28 Python
python实现人工蜂群算法
2020/09/18 Python
纯CSS3实现Material Design效果
2017/03/09 HTML / CSS
中国跨境在线时尚零售商:Bellelily
2018/04/06 全球购物
澳洲最大的时尚奢侈品电商平台:Cettire
2020/06/15 全球购物
以思科路由器为例你写下单臂路由的配置命令
2013/08/03 面试题
《那片绿绿的爬山虎》教学反思
2014/02/27 职场文书
大学生新学期计划书
2014/04/28 职场文书
毕业生找工作求职信
2014/08/05 职场文书
大学自主招生自荐信(2016精选篇)
2016/01/28 职场文书
2016年企业先进员工事迹材料
2016/02/25 职场文书
pytorch中的 .view()函数的用法介绍
2022/03/17 Python
Java中Dijkstra(迪杰斯特拉)算法
2022/05/20 Java/Android