高阶函数(higher-order-function)并不是 JavaScript 语言所特有的东西,它适用于整个计算机领域,甚至数学领域。
满足以下任一条件的函数都被称为高阶函数:

  1. 函数可以作为参数被传递(callback)或者说接收一个或多个函数作为输入
  2. 函数可以作为返回值输出(closer)

JavaScript 中的函数显然满足高阶函数的条件,在实际开发中,无论是将函数当作参数传递,还是让函数的执行结果返回另外一个函数,这两种情形都有很多应用场景。

15481514439261.jpg
15481514800226.jpg

函数是一等公民

在函数提升和变量提升的部分我们已知“函数是一等公民”这个说法了,当变量提升和函数提升同时存在,函数提升会在变量提升之前。函数可以像其他数据类型一样进入任何场所,可以:

  1. 被保存到变量中 let foo = function(){ }
  2. 作为参数传递 arr.sort( (a, b) => a-b )
  3. 作为返回值返回 closer ```javascript // 使用函数表达式定义函数,相当于是将函数保存到变量中 let foo = function(i){ … }

// 函数可以在变量之间传递,就像其他数据类型一样 let bar = foo;

// 函数可以当作参数直接传递 login(bar);

// 函数可以作为返回值返回,和其他数据类型一样 function foo(){ function random(){…} return random; }

  1. <a name="N4xbA"></a>
  2. ## 函数作为参数传递
  3. 把函数当作参数传递,代表可以抽离出一部分容易变化的业务逻辑,把这部分业务逻辑放在函数参数中,这样一来可以分离业务代码中 **变化 **与 **固定 **的部分。其中一个常见的应用场景就是回调函数。
  4. <a name="lOOxq"></a>
  5. ### 排序
  6. 对于数组的 sort() 方法想必已经非常熟悉了,该方法就接收一个函数作为参数。从 sort() 方法的使用可以看到,我们的目的是对数组进行排序,这是不变的部分;而使用什么规则去排序,则是可变的部分。<br />把可变的部分封装在函数参数里,动态传入 sort() 方法,使 sort() 函数成为了一个非常灵活的方法,所以 sort() 就属于一个高阶函数。
  7. 如果只是对数组中的数字进行排序就简单了:
  8. ```javascript
  9. arr.sort((a, b) => a - b);

在对扑克牌排序需求:当点数相等时,按花色排:

arr.sort((a, b) => {
  if(a.number == b.number){
    return a.flower - b.flower;
  }else{
    return a.number - b.number;
  }    
});

自定义高阶函数

首先思考一下高阶函数的所需要素,无非就是参数中需要一个函数,那如果代码写作:

function repeat(count, fn) {
  for (let i = 0; i < count; i++) {
    fn(); // 打印5次 被调用
  }
}
repeat(5, foo);

function foo() {
  console.log('被调用');
}

如果再换种方式玩这个函数:

function repeat(count, fn) {
  for (let i = 0; i < count; i++) {
    fn();
  }
}

repeat(10, function () {
  console.log("hello");
}); // 输出 10 个 hello

这种写法在哪里见过吗?addEventListener( ) 或者 setInterval( )中就见过这个写法对不对!

返回值输出

将函数作为返回值输出,看起来无非就是 return 出一个 function 咯?

// 该函数没有任何实际的意义,仅仅是一个 demo
function foo(){
    return function(a, b){
        console.log(a + b);
    }
}

当函数被调用:

let add = foo(); // 调用 foo 后接受到返回值 function 
add(1, 2); // 3
add('hello', 'world'); // hello world

(找个什么很厉害的封面图呢…害)