讲一讲JS中的高阶函数

“高阶函数”是个我们经常遇到的术语,英文名叫“higher-order function”,对于新手而言,还挺神秘。今天,我们就来探讨下高阶函数。

定义

接收函数作为参数或者返回函数的函数

大白话就是:

首先是个函数参数或者返回值是函数

举例子

我们这里举两个例子来覆盖下上文的定义,其中,例一为接收函数作为参数的高阶函数,例二为返回函数的高阶函数。

例一:函数作为参数

我们定义了一个叫evaluatesToFive的函数,接收两个参数:第一个参数是一个数字,第二个参数是一个函数。在函数evaluatesToFive中,将参数一(数字)传入参数二(函数)

<code>function evaluatesToFive(num, fn) {
return fn(num) === 5;
}/<code>

使用的场景:

<code>function divideByTwo(num) {
return num / 2;
}

evaluatesToFive(10, divideByTwo);
// true

evaluatesToFive(20, divideByTwo);
// false/<code>

哈哈,虽然函数本身用处不大,但是对描述高阶函数来说,很简单易懂。

例二:返回函数

本例中,我们创建函数multiplyBy,接收一个数字作为参数,并返回一个新的函数

<code>function multiplyBy(num1) {
return function(num2) {
return num1 * num2;
};
}/<code>

使用场景:

<code>const multiplyByThree = multiplyBy(3);
const multiplyByFive = multiplyBy(5);

multipyByThree(10); // 30

multiplyByFive(10); // 50/<code>

是不是有点感觉了,通过生成新的函数以达到更具体的目的。

更复杂的应用实例

本例中,我们创建一个函数去检测新用户的注册信息是否能通过检验规则:

大于18岁密码长度大于8同意用户协议

新用户的注册信息大概是这样:

<code>const newUser = {
age: 24,
password: 'some long password',
agreeToTerms: true,
};/<code>

接下来,我们来创建三个验证函数,通过返回true,否则返回false

<code>function oldEnough(user) {


return user.age >= 18;
}

function passwordLongEnough(user) {
return user.password.length >= 8;
}

function agreeToTerms(user) {
return user.agreeToTerms === true;
}/<code>

接下来,该主角登场了,我们需要创建一个高阶函数来一次性完成所有的验证。参数一是新用户注册信息,剩下的参数是我们上文创建的三个验证函数。在函数体中依次执行验证:

<code>function validate(obj, ...tests) {
for (let i = 0; i < tests.length; i++) {
if (tests[i](obj) === false) {
return false;
}
}
return true;
}/<code>

使用:

<code>

到目前为止,已经很棒了,继续看下去,看我们怎么改进

继续进化

上文中,我们使用validate函数的时候需要传入多个验证函数(oldEnough, passwordLongEnough, agreeToTerms),这违反了最少知识原则(有兴趣的同学们可以去了解下最少知识原则),看我们怎么将之继续改进:

<code>function createValidator(...tests) {
return function(obj) {
for (let i = 0; i < tests.length; i++) {
if (tests[i](obj) === false) {


return false;
}
}
return true;
};
}/<code>

这个createValidator函数牛逼了,它接收任意数量的函数作为参数,返回值也是个函数。所以这个createValidator也是个高阶函数。

使用:

<code>const userValidator = createValidator(
oldEnough,
passwordLongEnough,
agreeToTerms
);

userValidator(newUser1); // true
userValidator(newUser2); // false/<code>

看出什么门道了没?通过函数createValidator生成更具体的验证函数userValidator,再使用userValidator去验证新用户的注册信息。多么精彩的高阶函数!意犹未尽的同学们可以再学习下另一个术语柯里化!

结语

本小文,我们一起探讨了JS中的高阶函数,千万不要以为高阶函数只是一道面试题。前端框架中很火的高阶组件也是引用自高阶函数。高阶函数在我们日常开发中经常会使用到,用好了,可以将很多复杂的业务逻辑进行解耦,对于代码的可读性和可维护性很有意义!文中也用到了闭包的知识,聪明的你发现了吗?不要让自己的知识永远躺在面试题中哦!

以上内容都是我自己的一些感想,分享出来欢迎大家指正,顺便求一波关注,有问题或者需要学习资料的伙伴可以~


敲黑板

关注 +转发+私信“Java”

关注 +转发+私信“Java”

关注 +转发+私信“Java”