“高阶函数”是个我们经常遇到的术语,英文名叫“higher-order function”,对于新手而言,还挺神秘。今天,我们就来探讨下高阶函数。
定义
接收函数作为参数或者返回函数的函数
大白话就是:
- 首先是个函数
- 参数或者返回值是函数
举例子
我们这里举两个例子来覆盖下上文的定义,其中,例一为接收函数
作为参数的高阶函数,例二为返回函数
的高阶函数。
例一:函数作为参数
我们定义了一个叫evaluatesToFive
的函数,接收两个参数:第一个参数是一个数字,第二个参数是一个函数。在函数evaluatesToFive
中,将参数一(数字)传入参数二(函数)
function evaluatesToFive(num, fn) {
return fn(num) === 5;
}
使用的场景:
function divideByTwo(num) {
return num / 2;
}
evaluatesToFive(10, divideByTwo);
// true
evaluatesToFive(20, divideByTwo);
// false
哈哈,虽然函数本身用处不大,但是对描述高阶函数来说,很简单易懂。
例二:返回函数
本例中,我们创建函数multiplyBy
,接收一个数字作为参数,并返回一个新的函数
function multiplyBy(num1) {
return function(num2) {
return num1 * num2;
};
}
使用场景:
const multiplyByThree = multiplyBy(3);
const multiplyByFive = multiplyBy(5);
multipyByThree(10); // 30
multiplyByFive(10); // 50
是不是有点感觉了,通过生成新的函数以达到更具体的目的。
更复杂的应用实例
本例中,我们创建一个函数去检测新用户的注册信息是否能通过检验规则:
- 大于18岁
- 密码长度大于8
- 同意用户协议
新用户的注册信息大概是这样:
const newUser = {
age: 24,
password: 'some long password',
agreeToTerms: true,
};
接下来,我们来创建三个验证函数,通过返回true
,否则返回false
function oldEnough(user) {
return user.age >= 18;
}
function passwordLongEnough(user) {
return user.password.length >= 8;
}
function agreeToTerms(user) {
return user.agreeToTerms === true;
}
接下来,该主角登场了,我们需要创建一个高阶函数来一次性完成所有的验证。参数一是新用户注册信息,剩下的参数是我们上文创建的三个验证函数。在函数体中依次执行验证:
function validate(obj, ...tests) {
for (let i = 0; i < tests.length; i++) {
if (tests[i](obj) === false) {
return false;
}
}
return true;
}
使用:
const newUser1 = {
age: 40,
password: 'tncy4ty49r2mrx',
agreeToTerms: true,
};
validate(newUser1, oldEnough, passwordLongEnough, agreeToTerms);
// true
const newUser2 = {
age: 40,
password: 'short',
agreeToTerms: true,
};
validate(newUser2, oldEnough, passwordLongEnough, agreeToTerms);
// false
到目前为止,已经很棒了,继续看下去,看我们怎么改进
继续进化
上文中,我们使用validate
函数的时候需要传入多个验证函数(oldEnough, passwordLongEnough, agreeToTerms),这违反了最少知识原则
(有兴趣的同学们可以去了解下最少知识原则),看我们怎么将之继续改进:
function createValidator(...tests) {
return function(obj) {
for (let i = 0; i < tests.length; i++) {
if (tests[i](obj) === false) {
return false;
}
}
return true;
};
}
这个createValidator
函数牛逼了,它接收任意数量的函数作为参数,返回值也是个函数。所以这个createValidator
也是个高阶函数。
使用:
const userValidator = createValidator(
oldEnough,
passwordLongEnough,
agreeToTerms
);
userValidator(newUser1); // true
userValidator(newUser2); // false
看出什么门道了没?通过函数createValidator
生成更具体的验证函数userValidator
,再使用userValidator
去验证新用户的注册信息。多么精彩的高阶函数!意犹未尽的同学们可以再学习下另一个术语柯里化
!
结语
本小文,我们一起探讨了JS中的高阶函数,千万不要以为高阶函数只是一道面试题。前端框架中很火的高阶组件
也是引用自高阶函数。高阶函数在我们日常开发中经常会使用到,用好了,可以将很多复杂的业务逻辑进行解耦,对于代码的可读性和可维护性很有意义!文中也用到了闭包的知识,聪明的你发现了吗?不要让自己的知识永远躺在面试题中哦!