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 页面载入进度条实现代码
Feb 08 Javascript
html a标签-超链接中confirm方法使用介绍
Jan 04 Javascript
jQuery判断checkbox是否选中的小例子
Dec 02 Javascript
js写出遮罩层登陆框和对联广告并自动跟随滚动条滚动
Apr 29 Javascript
Bootstrap~多级导航(级联导航)的实现效果【附代码】
Mar 08 Javascript
完美的js图片轮换效果
Feb 05 Javascript
解决Extjs下拉框不显示的问题
Jun 21 Javascript
jQuery实现表单动态添加数据并提交的方法
Jul 19 jQuery
JS使用iView的Dropdown实现一个右键菜单
May 06 Javascript
layui实现把数据表格时间戳转换为时间格式的例子
Sep 12 Javascript
js 判断当前时间是否处于某个一个时间段内
Sep 19 Javascript
vue实现瀑布流组件滑动加载更多
Mar 10 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
解析smarty 截取字符串函数 truncate的用法介绍
2013/06/20 PHP
PHP通过反射动态加载第三方类和获得类源码的实例
2015/11/27 PHP
Laravel向公共模板赋值方法总结
2019/06/25 PHP
ASP.NET jQuery 实例6 (实现CheckBoxList成员全选或全取消)
2012/01/13 Javascript
javascript firefox 自动加载iframe 自动调整高宽示例
2013/08/27 Javascript
触屏中的JavaScript事件分析
2015/02/06 Javascript
学习JavaScript设计模式之责任链模式
2016/01/18 Javascript
微信小程序 删除项目工程实现步骤
2016/11/10 Javascript
轻松学习Javascript闭包
2017/03/01 Javascript
JS正则表达式验证账号、手机号、电话和邮箱是否合法
2017/03/08 Javascript
js 倒计时(高效率服务器时间同步)
2017/09/12 Javascript
微信小程序实现form表单本地储存数据
2019/06/27 Javascript
微信小程序中插入激励视频广告并获取收益(实例代码)
2019/12/06 Javascript
vue 项目引入echarts 添加点击事件操作
2020/09/09 Javascript
JavaScript中展开运算符及应用的实例代码
2021/01/14 Javascript
Python程序设计入门(1)基本语法简介
2014/06/13 Python
利用Python3分析sitemap.xml并抓取导出全站链接详解
2017/07/04 Python
pywinauto自动化操作记事本
2019/08/26 Python
python将三维数组展开成二维数组的实现
2019/11/30 Python
Python 随机生成测试数据的模块:faker基本使用方法详解
2020/04/09 Python
自定义Django_rest_framework_jwt登陆错误返回的解决
2020/10/18 Python
python爬虫看看虎牙女主播中谁最“顶”步骤详解
2020/12/01 Python
LivingSocial英国:英国本地优惠
2019/02/22 全球购物
数据库方面面试题
2012/04/22 面试题
学习委员自我鉴定
2014/01/13 职场文书
土木工程专业推荐信
2014/02/19 职场文书
2014年两会学习心得范例
2014/03/17 职场文书
美丽乡村建设实施方案
2014/03/23 职场文书
《最佳路径》教学反思
2014/04/13 职场文书
干部个人对照检查材料
2014/08/25 职场文书
公安四风对照检查材料思想汇报
2014/10/11 职场文书
公务员政审材料
2014/12/23 职场文书
给老婆道歉的话
2015/01/20 职场文书
校园运动会广播稿
2015/08/19 职场文书
《葡萄沟》教学反思
2016/02/23 职场文书
webpack介绍使用配置教程详解webpack介绍和使用
2022/06/25 Javascript