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 相关文章推荐
分析Node.js connect ECONNREFUSED错误
Apr 09 Javascript
js获取html页面节点方法(递归方式)
Dec 13 Javascript
控制台报错object is not a function的解决方法
Aug 24 Javascript
分享JavaScript与Java中MD5使用两个例子
Dec 23 Javascript
第一次接触神奇的Bootstrap表单
Jul 27 Javascript
使用vue编写一个点击数字计时小游戏
Aug 31 Javascript
jQuery如何跳转到另一个网页 就这么简单
Dec 28 Javascript
Vue2.x中的父子组件相互通信的实现方法
May 02 Javascript
PHP实现记录代码运行时间封装类实例教程
May 08 Javascript
React Native 自定义下拉刷新上拉加载的列表的示例
Mar 01 Javascript
element-ui组件中input等的change事件中传递自定义参数
May 22 Javascript
如何通过JS实现转码与解码
Feb 21 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
phpmyadmin中配置文件现在需要绝密的短语密码的解决方法
2007/02/11 PHP
PHP MySQL应用中使用XOR运算加密算法分享
2011/08/28 PHP
关于查看MSSQL 数据库 用户每个表 占用的空间大小
2013/06/21 PHP
PHP读取大文件的类SplFileObject使用介绍
2014/04/09 PHP
PHP实现深度优先搜索算法(DFS,Depth First Search)详解
2017/09/16 PHP
php高性能日志系统 seaslog 的安装与使用方法分析
2020/02/29 PHP
对jQuery的事件绑定的一些思考(补充)
2013/04/20 Javascript
分享Javascript中最常用的55个经典小技巧
2013/11/29 Javascript
使用jquery.qrcode生成彩色二维码实例
2014/08/08 Javascript
JavaScript DSL 流畅接口(使用链式调用)实例
2015/03/15 Javascript
JavaScript实现网页对象拖放功能的方法
2015/04/15 Javascript
javascript+html5实现绘制圆环的方法
2015/07/28 Javascript
js获取图片宽高的方法
2015/11/25 Javascript
JS实现复制内容到剪贴板功能
2017/02/05 Javascript
js中的触发事件对象event.srcElement与event.target详解
2017/03/15 Javascript
Three.js获取鼠标点击的三维坐标示例代码
2017/03/24 Javascript
react-native ListView下拉刷新上拉加载实现代码
2017/08/03 Javascript
JS运动特效之完美运动框架实例分析
2018/01/24 Javascript
Vue中的vue-resource示例详解
2018/11/02 Javascript
微信jssdk逻辑在vue中的运用详解
2018/11/14 Javascript
JQuery+drag.js上传图片并且实现图片拖曳
2020/11/18 jQuery
详解Python中contextlib上下文管理模块的用法
2016/06/28 Python
python 编程之twisted详解及简单实例
2017/01/28 Python
python爬虫获取淘宝天猫商品详细参数
2020/06/23 Python
Python中判断输入是否为数字的实现代码
2018/05/26 Python
python自制包并用pip免提交到pypi仅安装到本机【推荐】
2019/06/03 Python
PyQT实现菜单中的复制,全选和清空的功能的方法
2019/06/17 Python
HTML5 Canvas 破碎重组的视频特效的示例代码
2019/09/24 HTML / CSS
Zavvi西班牙:电子游戏、极客服装、Blu-ray、Funko Pop等
2019/05/03 全球购物
经典优秀毕业生求职信范文分享
2013/12/18 职场文书
运动会稿件100字
2014/02/21 职场文书
助人为乐模范事迹材料
2014/06/02 职场文书
基层工作经历证明
2015/06/19 职场文书
《刷子李》教学反思
2016/02/20 职场文书
Spring Data JPA框架自定义Repository接口
2022/04/28 Java/Android
MySQL 原理与优化之原数据锁的应用
2022/08/14 MySQL