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 相关文章推荐
JavaScript去掉数组中的重复元素
Jan 13 Javascript
javascript高级学习笔记整理
Aug 14 Javascript
Javascript图像处理—亮度对比度应用案例
Jan 03 Javascript
浅谈javascript中的instanceof和typeof
Feb 27 Javascript
使用微信内置浏览器点击下拉框出现页面乱跳转现象(iphone),该怎么办
Jan 04 Javascript
深入学习jQuery Validate表单验证(二)
Jan 18 Javascript
AngularJs 指令详解及示例代码
Sep 01 Javascript
Bootstrap Table的使用总结
Oct 08 Javascript
EasyUI的DataGrid每行数据添加操作按钮的实现代码
Aug 22 Javascript
JavaScript代码调试方法实例小结
Jan 05 Javascript
JavaScript中BOM对象原理与用法分析
Jul 09 Javascript
H5+css3+js搭建带验证码的登录页面
Oct 11 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
Zend Guard一些常见问题解答
2008/09/11 PHP
Window下PHP三种运行方式图文详解
2013/06/11 PHP
解析PHP对现有搜索引擎的调用
2013/06/25 PHP
php判断GIF图片是否为动画的方法
2020/09/04 PHP
8个PHP数组面试题
2015/06/23 PHP
完美解决Thinkphp3.2中插入相同数据的问题
2017/08/01 PHP
[HTML/CSS/Javascript]WWTJS
2007/09/25 Javascript
工作中常用到的JS表单验证代码(包括例子)
2010/11/11 Javascript
javascript 窗口加载蒙板 内嵌网页内容
2010/11/19 Javascript
浅析JavaScript中的常用算法与函数
2013/11/21 Javascript
ionic js 复选框 与普通的 HTML 复选框到底有没区别
2016/06/06 Javascript
bootstrap选项卡使用方法解析
2017/01/11 Javascript
canvas知识总结
2017/01/25 Javascript
Vue 表单控件绑定的实现示例
2017/08/11 Javascript
vue 2.0 购物车小球抛物线的示例代码
2018/02/01 Javascript
angularjs实现的购物金额计算工具示例
2018/05/08 Javascript
vue.js图片转Base64上传图片并预览的实现方法
2018/08/02 Javascript
vue移动端下拉刷新和上滑加载
2020/10/27 Javascript
vue实现轮播图帧率播放
2021/01/26 Vue.js
Python写入数据到MP3文件中的方法
2015/07/10 Python
Python利用openpyxl库遍历Sheet的实例
2018/05/03 Python
Python3.6日志Logging模块简单用法示例
2018/06/14 Python
对python3标准库httpclient的使用详解
2018/12/18 Python
python之信息加密题目详解
2019/06/26 Python
pandas进行时间数据的转换和计算时间差并提取年月日
2019/07/06 Python
python线程join方法原理解析
2020/02/11 Python
python中if及if-else如何使用
2020/06/02 Python
浅谈keras中Dropout在预测过程中是否仍要起作用
2020/07/09 Python
美国LOGO设计公司:The Logo Company
2018/07/16 全球购物
介绍下Java的输入输出流
2014/01/22 面试题
酒店led欢迎词
2014/01/09 职场文书
经贸日语专业个人求职信范文
2014/04/29 职场文书
企业安全生产月活动总结
2014/07/05 职场文书
2015年先进个人自荐书
2015/03/24 职场文书
2015安全保卫工作总结
2015/04/25 职场文书
新闻稿怎么写
2015/07/18 职场文书