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 相关文章推荐
JS对select控件option选项的增删改查示例代码
Oct 21 Javascript
js实现多选项切换导航菜单的方法
Feb 06 Javascript
BootStrap响应式导航条实例介绍
May 06 Javascript
jQuery中Nicescroll滚动条插件的用法
Nov 10 Javascript
javascript中Number的方法小结
Nov 21 Javascript
js中删除数组中的某一元素实例(无下标时)
Feb 28 Javascript
大白话讲解JavaScript的Promise
Apr 06 Javascript
使用canvas进行图像编辑的实例
Aug 29 Javascript
CheckBox多选取值及判断CheckBox选中是否为空的实例
Oct 31 Javascript
Vue + Vue-router 同名路由切换数据不更新的方法
Nov 20 Javascript
利用Webpack实现小程序多项目管理的方法
Feb 25 Javascript
JavaScript图像放大镜效果实现方法详解
Jun 28 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
一个用php3编写的简单计数器
2006/10/09 PHP
解析PHP中VC6 X86和VC9 X86的区别及 Non Thread Safe的意思
2013/06/28 PHP
php函数间的参数传递(值传递/引用传递)
2013/09/23 PHP
PHP中的替代语法简介
2014/08/22 PHP
thinkPHP商城公告功能开发问题分析
2016/12/01 PHP
PHP双向链表定义与用法示例
2018/01/31 PHP
IE不出现Flash激活框的小发现的js实现方法
2007/09/07 Javascript
javascript 获取select下拉列表值的代码
2009/09/07 Javascript
JS 日期验证正则附asp日期格式化函数
2009/09/11 Javascript
js 变量类型转换常用函数与代码[比较全]
2009/12/01 Javascript
JavaScript中的继承方式详解
2015/02/11 Javascript
使用AngularJS处理单选框和复选框的简单方法
2015/06/19 Javascript
JavaScript实现自动生成网页元素功能(按钮、文本等)
2015/11/21 Javascript
js图片跟随鼠标移动代码
2015/11/26 Javascript
js中最容易被忽视的事件问题大总结
2016/05/15 Javascript
AngularJS基础 ng-init 指令简单示例
2016/08/02 Javascript
原生JS:Date对象全面解析
2016/09/06 Javascript
ajax实现动态下拉框示例
2017/01/10 Javascript
bootstrap组件之按钮式下拉菜单小结
2017/01/19 Javascript
人工智能最火编程语言 Python大战Java!
2017/11/13 Python
Python使用flask框架操作sqlite3的两种方式
2018/01/31 Python
Python IDLE清空窗口的实例
2018/06/25 Python
Pycharm无法显示动态图片的解决方法
2018/10/28 Python
使用Python获取网段IP个数以及地址清单的方法
2018/11/01 Python
在Python中输入一个以空格为间隔的数组方法
2018/11/13 Python
在Pycharm中对代码进行注释和缩进的方法详解
2019/01/20 Python
python如何实现图片压缩
2020/09/11 Python
Pytorch如何切换 cpu和gpu的使用详解
2021/03/01 Python
基于 HTML5 WebGL 实现的医疗物流系统
2019/10/08 HTML / CSS
阿联酋航空官方网站:Emirates
2017/10/17 全球购物
2016年艾滋病宣传活动总结
2016/04/01 职场文书
新学期新寄语,献给新生们!
2019/11/15 职场文书
CSS的class与id常用的命名规则
2021/05/18 HTML / CSS
Python 如何将integer转化为罗马数(3999以内)
2021/06/05 Python
分享五个Node.js开发的优秀实践 
2022/04/07 NodeJs
BCL经典机 SONY ICF-5900W电路分析
2022/04/24 无线电