【JS】140-重温基础:高阶函数_高阶函数

本文是 重温基础 系列文章的第二十一篇。
今日感受:想家。

本章节复习的是JS中的高阶函数,可以提高我们的开发效率。

1.介绍

个人简单理解为,一个函数可以接收其他函数作为参数,这种函数便称为高阶函数,而主要目的就是为了能接收其他函数作为参数。

Q: 为什么可以接收一个函数作为参数?
A: 因为函数可以接收变量作为参数,而变量可以声明一个方法。

简单实例:

  1. function a (x){
  2.    return 'hi ' + x;
  3. }
  4. function f (a, b){
  5.    return a(b);
  6. }
  7. f(a, 'leo');   // "hi leo"

这段代码的意思:定义方法 ​f​​,接收两个参数,方法 ​a​​和变量 ​b​​,在方法 ​a​​中返回一段字符串,当执行方法 ​f​​并传入参数方法 ​a​​和参数 ​b​​的时候,返回 ​"hi leo"​。

也可以直接调用JS内置方法:

  1. let a = 3, b = -2;
  2. function my_abs (val, fun){
  3.    return fun(val);
  4. }
  5. my_abs(a, Math.abs);  // 3
  6. my_abs(b, Math.abs);  // 2


2.常用高阶函数

2.1 map()

map()​方法的作用是:接收一个函数作为参数,对数组中每个元素按顺序调用一次传入的函数并返回结果,不改变原数组,返回一个新数组
通常使用方式: ​​arr.map(callback())​​,更多详细介绍可以参考 MDN Array.map()。
参数

  • arr​ : 需要操作的数组;
  • callback(currentValue,index,array,thisArg)​ : 处理的方法,四个参数;
  • ​currentVthisArgalue​​​ 执行 ​​callback​​ 函数时使用的 ​​this​​ 值,可选
  • ​array​​​ 调用 ​​map()​​方法的数组,可选
  • ​index​​ 当前处理的元素的索引,可选
  • ​currentValue​​ 当前处理的元素的

返回值
返回一个处理后的新数组。

实例

  1. let arr = [1, 3, -5];
  2. let a1 = arr.map(Math.abs);  
  3. // a1 => [1, 3, 5];

  4. let a2 = arr.map(String);
  5. // a2 => ["1", "3", "-5"]

  6. let a3 = arr.map(function (x){
  7.    return x + 1;
  8. })
  9. // 等价于 a3=arr.map(x => x+1)
  10. // a3 => [2, 4, -4]

对比 ​for...in​​ 循环, ​map()​书写起来更加简洁:

  1. let arr = [1, 3, -5];
  2. let a1 = [];
  3. for (var i=0; i<arr.length; i++){
  4.    a1.push(arr[i] + 1);
  5. }
  6. // a1 => [2, 4, -4]

map()​作为高阶函数,事实上它把运算规则抽象了。

2.2 reduce()

reduce()​方法的作用是:接收一个函数,对数组进行累加操作,把累计结果和下一个值进行操作,最后返回最终的单个结果值。

通常使用方式: ​arr.reduce(callback(),initValue)​,更多详细介绍可以参考 MDN Array.reduce()

参数

  • callback(returnValue,currentValue,currentIndex,array)​ : 累记器的方法,四个参数:
  • ​array​​​ 调用 ​​reduce()​​方法的数组,可选
  • ​currentIndex​​ 当前处理的元素的索引,可选
  • ​currentValue​​ 当前处理的元素的,可选
  • ​returnValue​​ 上一次处理的返回值,或者初始值
  • initValue​​ 初次调用 ​​callback()​​时候 ​​returnValue​​参数的初始值,默认数组第一个元素,可选

返回值
返回一个最终的累计值。

实例

  1. 数组求和
  2. let arr = [1, 3, -5];
  3. let sum1 = arr.reduce((res, cur) => res + cur);
  4. // sum1 => -1

  5. let sum2 = arr.reduce((res, cur) => res + cur , 1);
  6. // sum1 => 0
  7. 二维数组转化为一维
  8. let arr = [[1, 2], [3, 4], [5, 6]];
  9. let con = arr.reduce((res, cur) => res.concat(cur));
  10. // con => [1, 2, 3, 4, 5, 6]

2.3 filter()

filter()​方法的作用是:接收一个函数,依次作用数组每个元素,并过滤符合函数条件的元素,将剩下的数组作为一个新数组返回。

通常使用方式: ​arr.filter(callback(),thisArg)​,更多详细介绍可以参考 MDN Array.filter()

参数

  • callback(ele,index,array)​​ : 过滤条件的方法,当返回 ​​true​​则保存该元素,反之不保留,三个参数:
  • ​array​​​ 调用 ​​filter()​​方法的数组,可选
  • ​index​​ 当前处理的元素的索引,可选
  • ​ele​​ 当前处理的元素
  • thisArg​​ 执行 ​​callback​​ 时的用于 ​​this​​ 的值,可选

返回值
返回一个过滤剩下的元素组成的新数组。

实例

  1. 过滤奇数值
  2. let arr = [1, 2, 3, 4, 5, 6];
  3. let res = arr.filter(x => x % 2 != 0);
  4. // res => [1, 3, 5]
  5. 过滤不满足条件的值
  6. let arr = [1, 2, 3, 4, 5, 6];
  7. let res = arr.filter(x => x > 3);
  8. // res => [4, 5, 6]
  9. 过滤空字符串
  10. let arr = ['a', '', null, undefined, 'b', ''];
  11. let tri = arr.filter(x => x && x.trim());
  12. // tri => ["a", "b"]

总结下: ​filter()​主要作为筛选功能,因此核心就是正确实现一个“筛选”函数。

2.4 sort()

sort()​方法的作用是:接收一个函数,对数组的元素进行排序,并返回排序后的新数组。默认排序顺序是根据字符串Unicode码点

通常使用方式: ​arr.sort(fun())​,更多详细介绍可以参考 MDN Array.sort()compareFunction 可选 用来指定按某种顺序进行排列的函数。如果省略,元素按照转换为的字符串的各个字符的Unicode位点进行排序。参数

  • fun(a,b)​​ : 指定按某种顺序进行排列的函数,若省略则按照转换为的字符串的各个字符的Unicode位点进行排序,两个可选参数:
    ​fun()​​ 返回 ​​a​​和 ​​b​​两个值的大小的比较结果, ​​sort()​​根据返回结果进行排序:
  • 若 ​fun(a,b)​​ 小于 0 ,则 ​​a​​ 排在 ​​b​​ 前面;
  • 若 ​fun(a,b)​​ 等于 0 ,则 ​​a​​ ​​b​​ 位置不变;
  • 若 ​fun(a,b)​​ 大于 0 ,则 ​​a​​ 排在 ​​b​​ 后面;

返回值
返回排序后的新数组,并修改原数组

实例

  1. 升序降序数组
  2. let arr = [1,5,2,3];
  3. let sort1 = arr.sort();
  4. // 等同于 let sort1 = arr.sort((a, b) => a - b);
  5. // sort1 => [1, 2, 3, 5]

  6. let sort2 = arr.sort((a, b) => b - a);
  7. // sort2 => [5, 3, 2, 1]
  8. 字符串排序
  9. let arr1 = ['AA', 'CC', 'BB'];
  10. let sort1 = arr1.sort();
  11. // sort1 => ["AA", "BB", "CC"]

  12. let arr2 = ['AA', 'aa', 'BB'];
  13. let sort2 = arr2.sort();
  14. // sort2 => ["AA", "BB", "aa"]

  15. let arr3 = ['AA', 'aa', 'BB'];
  16. let sort3 = arr3.sort((a, b) => a.toLowerCase() > b.toLowerCase());
  17. // sort3 => ["AA", "aa", "BB"]
  18. // 也可以写成:
  19. let sort3 = arr3.sort((a, b) => {
  20.    let s1 = a.toLowerCase();
  21.    let s2 = b.toLowerCase();
  22.    return s1 > s2 ? 1 : s1 < s2 ? -1 : 0;
  23. })

总结下: ​sort()​主要作为排序功能,因此核心就是正确实现一个“排序”函数。

3. 参考文章

  • 阮一峰 JS高阶函数

【JS】140-重温基础:高阶函数_字符串_02