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 Plugin 插件的方法
Apr 20 Javascript
在jQuery ajax中按钮button和submit的区别分析
Oct 07 Javascript
借助javascript代码判断网页是静态还是伪静态
May 05 Javascript
jQuery选择器源码解读(四):tokenize方法的Expr.preFilter
Mar 31 Javascript
Laydate时间组件在火狐浏览器下有多时间输入框时只能给第一个输入框赋值的解决方法
Aug 18 Javascript
探究Vue.js 2.0新增的虚拟DOM
Oct 20 Javascript
基于原生js淡入淡出函数封装(兼容IE)
Oct 20 Javascript
JavaScript仿聊天室聊天记录
Dec 27 Javascript
JavaScript实现的选择排序算法实例分析
Apr 14 Javascript
react-redux中connect()方法详细解析
May 27 Javascript
vue cli 3.0 使用全过程解析
Jun 14 Javascript
Vue实现导航栏的显示开关控制
Nov 01 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
MySQL相关说明
2007/01/15 PHP
PHP执行批量mysql语句的解决方法
2013/05/02 PHP
php中curl和file_get_content的区别
2014/05/10 PHP
ThinkPHP之用户注册登录留言完整实例
2014/07/22 PHP
注释PHP和html混合代码的小技巧(分享)
2016/11/03 PHP
php实现购物车功能(以大苹果购物网为例)
2017/03/09 PHP
php cli模式下获取参数的方法
2017/05/05 PHP
详解PHP的抽象类和抽象方法以及接口总结
2019/03/15 PHP
锋利的jQuery 要点归纳(三) jQuery中的事件和动画(上:事件篇)
2010/03/24 Javascript
JQuery中使用Ajax赋值给全局变量异常的解决方法
2014/01/10 Javascript
纯javascript实现的小游戏《Flappy Pig》实例
2015/07/27 Javascript
JS实现浏览器状态栏文字闪烁效果的方法
2015/10/27 Javascript
解决angular的$http.post()提交数据时后台接收不到参数值问题的方法
2015/12/10 Javascript
Bootstrap框架下下拉框select搜索功能
2020/03/26 Javascript
详解Angualr 组件间通信
2017/01/21 Javascript
ES6模块化的import和export用法方法总结
2017/08/08 Javascript
jquery动态赋值id与动态取id方法示例
2017/08/21 jQuery
vue 项目常用加载器及配置详解
2018/01/22 Javascript
vue中axios解决跨域问题和拦截器的使用方法
2018/03/07 Javascript
mint-ui在vue中的使用示例
2018/04/05 Javascript
vue移动端微信授权登录插件封装的实例
2018/08/28 Javascript
vue实现输入框自动跳转功能
2020/05/20 Javascript
Vue Element校验validate的实例
2020/09/21 Javascript
浅谈Python Opencv中gamma变换的使用详解
2018/04/02 Python
深入理解Django-Signals信号量
2019/02/19 Python
python multiprocessing模块用法及原理介绍
2019/08/20 Python
Python对称的二叉树多种思路实现方法
2020/02/28 Python
python爬虫---requests库的用法详解
2020/09/28 Python
几款Python编译器比较与推荐(小结)
2020/10/15 Python
美国非常受欢迎的Spa品牌:Bliss必列斯
2018/04/10 全球购物
团日活动策划书
2014/02/01 职场文书
如何写股份合作协议书
2014/09/11 职场文书
交通事故被告答辩状
2015/05/22 职场文书
党性教育心得体会(共6篇)
2016/01/21 职场文书
Python离线安装openpyxl模块的步骤
2021/03/30 Python
mysql脏页是什么
2021/07/26 MySQL