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的开发个代阴影的对话框效果代码
Jul 28 Javascript
javascript SpiderMonkey中的函数序列化如何进行
Dec 05 Javascript
jQuery实现跟随鼠标运动图层效果的方法
Feb 02 Javascript
Vue ElementUI之Form表单验证遇到的问题
Aug 21 Javascript
原生JS实现移动端web轮播图详解(结合Tween算法造轮子)
Sep 10 Javascript
利用JS判断客户端类型你应该知道的四种方法
Dec 22 Javascript
VUE2.0+Element-UI+Echarts封装的组件实例
Mar 02 Javascript
vuex 的简单使用
Mar 22 Javascript
10分钟上手vue-cli 3.0 入门介绍
Apr 04 Javascript
Vue.set 全局操作简单示例
Sep 19 Javascript
vue 使用 vue-pdf 实现pdf在线预览的示例代码
Apr 26 Javascript
基于JavaScript实现猜数字游戏代码实例
Jul 30 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中autoload的用法总结
2013/11/08 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十三)
2014/06/26 PHP
php邮箱地址正则表达式验证
2015/11/13 PHP
php用户密码加密算法分析【Discuz加密算法】
2016/10/12 PHP
PHP中的自动加载操作实现方法详解
2019/08/06 PHP
JavaScript Undefined,Null类型和NaN值区别
2008/10/22 Javascript
js 对联广告、漂浮广告封装类(IE,FF,Opera,Safari,Chrome
2009/11/26 Javascript
js判断一个元素是否为另一个元素的子元素的代码
2012/03/21 Javascript
js/jQuery对象互转(快速操作dom元素)
2013/02/04 Javascript
js中onload与onunload的使用示例
2013/08/25 Javascript
js window.onload 加载多个函数和追加函数详解
2014/01/08 Javascript
jQuery实现非常实用漂亮的select下拉菜单选择效果
2015/11/06 Javascript
javascript:void(0)是什么意思及href=#与href=javascriptvoid(0)的区别
2015/11/13 Javascript
jQuery基于muipicker实现仿ios时间选择
2016/02/22 Javascript
微信小程序实现人脸检测功能
2018/05/25 Javascript
vue表单自定义校验规则介绍
2018/08/28 Javascript
vue路由传参三种基本方式详解
2019/12/09 Javascript
Vue数据双向绑定原理实例解析
2020/05/15 Javascript
Vue.js中使用Vuex实现组件数据共享案例
2020/07/31 Javascript
JavaScript实现简单日历效果
2020/09/11 Javascript
[02:42]DOTA2城市挑战赛收官在即 四强之争风起云涌
2018/06/05 DOTA
python学习笔记之列表(list)与元组(tuple)详解
2017/11/23 Python
Python序列循环移位的3种方法推荐
2018/04/09 Python
python selenium自动上传有赞单号的操作方法
2018/07/05 Python
将python安装信息加入注册表的示例
2019/11/20 Python
Python检测端口IP字符串是否合法
2020/06/05 Python
一款纯css3实现的tab选项卡的实列教程
2014/12/11 HTML / CSS
基于HTML5 WebGL的3D机房的示例
2018/03/16 HTML / CSS
黄金搭档广告词
2014/03/21 职场文书
美丽家庭事迹材料
2014/05/03 职场文书
质量安全标语
2014/06/07 职场文书
小学语文教研活动总结
2014/07/01 职场文书
党的群众路线对照检查材料思想汇报
2014/09/25 职场文书
关于随地扔垃圾的检讨书
2014/09/30 职场文书
三好学生评选事迹材料(2016精选版)
2016/02/25 职场文书
jQuery实现广告显示和隐藏动画
2021/07/04 jQuery