函数式编程(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