函数式编程(1)
来源:互联网 发布:华为荣耀盒子安装软件 编辑:程序博客网 时间:2024/05/22 07:59
重构
我们先来看一段重构问题,这里有一些js片段
function validateSsn(ssn){ if(/^\d{3}-\d{2}-\d{4}$/.exec(ssn)){ console.log('Valid SSN'); } else { console.log('Invalid SSN'); } } function validatePhone(phone){ if(/^(\d{3})-\d{3}-\d{4}$/.exec(phone)){ console.log('Valid Phone Number'); } else { console.log('Invalid Phone Number'); } }
我们发现两个函数功能相同,只有一小部分不一样。正常我们考虑抽离出变化的参数value, regular expression, 和打印的message。
重构后的代码
function validateValue(value, regex, type){ if(regex.exec(value)){ console.log('Valid' + type); } else { console.log('Invalid' + type); } }
使用一个函数要比使用两个函数要好一些,这使得代码整洁并且可维护。例如,发现一个bug,只需要修改一个地方,而不是搜索整个代码库来查找可能粘贴并修改整个函数的地方。
但是有如下的情况会怎么样
function valiadateAddress(address){ if(parseAddress(address)){ console.log('Valid Address'); } else { console.log('Invalid Address'); } } function valiadateName(name){ if(parseFullName(name)){ console.log('Valid Name'); } else { console.log('Invalid Name'); } }
在这parseAddress和parseFullName函数都是接受一个string,如果传入的字符串符合预订的句法则返回true。我们该如何来重构这段代码?我们可以像前面一样使用value来代表address和name,使用type来代表’Address’和’Name’,但我们的正则表达式在这里是一个函数
如果我们可以将一个函数作为参数传递
高阶函数
许多语言不支持将函数作为函数传递,有的支持但变得非常复杂。而在函数式语言中,函数是这个语言中的一等公民,换句话说,函数仅仅是一种值而已。由于函数仅仅是值,我们可以将它们作为参数传递:
function valiateValueWithFunc(value, parseFunc, type){ // 是不是想起了我们平时传callback进去的时候 if(pareseFunc(value)){ console.log('Invalid' + type); } else { console.log('Valid' + type); } }
我们的新函数就称为高阶函数(Higher-order-Function)。
高阶函数可以接受函数作为参数,或者返回一个函数结果,或者两者具备。
接下来我们看一下我们的正则表达式,每次都要添加.exec
到它的末尾,可以通过创建一个返回exec函数的高阶函数来防止这种情况
function makeRegexParser(regex){ return regex.exec; } // 原本是var parseSsn = /^\d{3}-\d{2}-\d{4}$/.exec; var parseSsn = makeRegexParser(/^\d{3}-\d{2}-\d{4}$/); valiateValueWithFunc('...', parseSsn, 'SSN');
的确这是一个微不足道的改进,但是这里展示了一个高阶函数返回一个函数的例子。
下面再看另一个例子
function makeAdder(constantValue){ return function add(value){ return constantValue + value; } }
看一下它怎么使用
// 保存一个函数引用 var add10 = makeAdder(10); // 调用它 console.log(add10(20)); // 30 console.log(add10(30)); // 40
add函数通过闭包保存了constantValue的值。
0 0
- 函数式编程(1)
- 1 函数式编程
- scala(1:函数式编程)
- 函数式编程入门教程(1)
- 函数式编程另类指南1
- [Java 8] (1) 函数式编程简介
- commons之函数式编程1_Predicate_TransformerJAVA138
- Scala 函数式编程进阶 (1)
- [Java 8] (1) 函数式编程简介
- 函数式编程的记录1
- [Java 8] (1) 函数式编程简介
- JS函数式编程(1)
- scala(1:函数式编程新)
- 函数式编程
- 函数式编程
- 函数式编程
- 函数式编程
- 另类函数式编程
- Unity教程之-Unity Attribute的使用总结
- jdk1.8 concurrenthashmap
- 【Ubuntu 16】 SSH免密码登录
- SpringMVC
- 机器学习简介
- 函数式编程(1)
- JAVA深复制(深克隆)与浅复制(浅克隆)
- angularjs-路由
- 堆和栈的区别(被转载过无数次的文章)
- Mybatis 的分页插件PageHelper-4.1.1的使用
- 插件化知识详细分解及原理 之ClassLoader及dex加载过程
- jvm-监控指令-jstack
- Jquery之绑定事件的三种方法(.bind .live .on .delegate )
- apache-tomcat-7.0.57的一个BUG,文件上传时超过设定的值,页面无状态无响应