JS中的高阶函数

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

定义

接收函数做为参数或者返回函数的函数面试

大白话就是:bash

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

举例子

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

例一:函数做为参数

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

function evaluatesToFive(num, fn) {
  return fn(num) === 5;
}
复制代码

使用的场景:闭包

function divideByTwo(num) {
  return num / 2;
}

evaluatesToFive(10, divideByTwo);
// true

evaluatesToFive(20, divideByTwo);
// false
复制代码

哈哈,虽然函数自己用处不大,可是对描述高阶函数来讲,很简单易懂。框架

例二:返回函数

本例中,咱们建立函数multiplyBy,接收一个数字做为参数,并返回一个新的函数ide

function multiplyBy(num1) {
  return function(num2) {
    return num1 * num2;
  };
}
复制代码

使用场景:函数

const multiplyByThree = multiplyBy(3);
const multiplyByFive = multiplyBy(5);

multipyByThree(10); // 30

multiplyByFive(10); // 50
复制代码

是否是有点感受了,经过生成新的函数以达到更具体的目的。oop

更复杂的应用实例

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

  • 大于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中的高阶函数,千万不要觉得高阶函数只是一道面试题。前端框架中很火的高阶组件也是引用自高阶函数。高阶函数在咱们平常开发中常常会使用到,用好了,能够将不少复杂的业务逻辑进行解耦,对于代码的可读性和可维护性颇有意义!文中也用到了闭包的知识,聪明的你发现了吗?不要让本身的知识永远躺在面试题中哦!

相关文章
相关标签/搜索