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 相关文章推荐
prototype class详解
Sep 07 Javascript
Javascript this指针
Jul 30 Javascript
25个优雅的jQuery Tooltip插件推荐
May 25 Javascript
js的隐含参数(arguments,callee,caller)使用方法
Jan 28 Javascript
jQuery使用andSelf()来包含之前的选择集
May 19 Javascript
javascript强制点击广告的方法
Feb 06 Javascript
微信小程序 wx.request(OBJECT)发起请求详解
Oct 13 Javascript
jquery控制页面的展开和隐藏实现方法(推荐)
Oct 15 Javascript
Bootstrap基本插件学习笔记之Alert警告框(20)
Dec 08 Javascript
微信小程序 天气预报开发实例代码源码
Jan 20 Javascript
深入理解vue-loader如何使用
Jun 06 Javascript
详解Vue + Vuex 如何使用 vm.$nextTick
Nov 20 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中的日期及时间
2006/11/23 PHP
解析PHP高效率写法(详解原因)
2013/06/20 PHP
PHP变量的定义、可变变量、变量引用、销毁方法
2013/12/20 PHP
php读取excel文件示例分享(更新修改excel)
2014/02/27 PHP
PHP Post获取不到非表单数据的问题解决办法
2018/02/27 PHP
JsEasy简介 JsEasy是什么?与下载
2007/03/07 Javascript
Javascript模块模式分析
2008/05/16 Javascript
判断iframe是否加载完成的完美方法
2010/01/07 Javascript
使用jQuery模板来展现json数据的代码
2010/10/22 Javascript
推荐11款jQuery开发的复选框和单选框美化插件
2011/08/02 Javascript
详解Angular.js的$q.defer()服务异步处理
2016/11/06 Javascript
javascript刷新父页面方法汇总详解
2019/10/10 Javascript
JavaScript中如何对多维数组(矩阵)去重的实现
2019/12/04 Javascript
VUE中使用HTTP库Axios方法详解
2020/02/05 Javascript
在vue中使用eslint,配合vscode的操作
2020/11/09 Javascript
Vue项目如何引入bootstrap、elementUI、echarts
2020/11/26 Vue.js
vue项目中openlayers绘制行政区划
2020/12/24 Vue.js
python生成ppt的方法
2018/06/07 Python
Python enumerate函数功能与用法示例
2019/03/01 Python
Python自动化导出zabbix数据并发邮件脚本
2019/08/16 Python
Python内置异常类型全面汇总
2020/05/28 Python
利用Python过滤相似文本的简单方法示例
2021/02/03 Python
CSS书写规范、顺序和命名规则
2014/03/06 HTML / CSS
详解CSS3新增的背景属性
2019/12/25 HTML / CSS
AE美国鹰美国官方网站:American Eagle Outfitters
2016/08/22 全球购物
TUMI新加坡官网:国际领先的商旅箱包品牌
2019/01/12 全球购物
以思科路由器为例你写下单臂路由的配置命令
2013/08/03 面试题
应聘护士自荐信
2013/10/21 职场文书
外贸业务员求职信
2014/06/16 职场文书
企业法人授权委托书
2014/09/25 职场文书
购房协议书范本(无房产证)
2014/10/07 职场文书
2014年市场部工作总结
2014/11/25 职场文书
财务人员岗位职责
2015/02/03 职场文书
供应商食品安全承诺书
2015/04/29 职场文书
Python中的xlrd模块使用整理
2021/06/15 Python
Vue图片裁剪组件实例代码
2021/07/02 Vue.js