felix-cao / Blog

A little progress a day makes you a big success!
31 stars 4 forks source link

JavaScript 高阶函数(Higher-order function) #110

Open felix-cao opened 5 years ago

felix-cao commented 5 years ago

一、什么是高阶函数

高阶函数英文叫 Higher-order functionJavaScript 的函数其实都指向某个变量。既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。 由此看来,高阶函数是指至少满足以下条件之一的函数:

JavaScript 语言中,函数是一等对象/公民,函数本身可以被四处传递。JavaScript 数组提供了如下几个常见的高阶函数:

命令 Notes
1. map 返回新数组,新数组的元素为原数组元素经回调函数处理后的值
2. reduce 高阶函数
3. filter 高阶函数, 返回新数组
4. some 检测数组中的元素是否满足指定条件(函数提供)
5. every 检测数组所有元素是否都符合指定条件(通过函数提供)

二、map(fn) 方法遍历数组

map(fn) 方法接收一个函数 fn 作用参数,当循环一个数组时,会将当前元素的值,索引及整个数组集合作为fn函数的三个参数传递给 fn 函数,经 fn 函数处理后返回一个新的数组。 map() 方法的用法与 forEach() 非常相似,当然也有不同点。

array.map(function(currentValue, [index], [arr]){ ... }, [thisValue]);

map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。 map() 方法按照原始数组元素顺序依次处理元素。 注意:map() 不会改变原始数组。

相同点:

不同点:

function pow(x) {
    console.log('return new Item: ', x*x);
    return x * x;
}

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let results = arr.map(pow); // 返回一个新的数组,[1, 4, 9, 16, 25, 36, 49, 64, 81]
console.log(results);

三、reduce(fn) 方法遍历数组

array.reduce(function(accumulator, currentValue, [currentIndex], [array]){ ... }, [initialValue]);

map(fn) 方法类似,reduce(fn) 方法接收一个函数 fn 作用参数,当循环一个数组时,会将累加器(accumulator),当前元素的值,索引及整个数组集合作为fn函数的四个参数传递给 fn 函数,最终返回累加器的值。

initialValue 可以设置累加器的默认值,若不设置,则数组的第一个元素作为累加器的值。

let arr = [1, 3, 5, 7, 9];
let total = arr.reduce(function (acc, currentValue, currentIndex, array) {
  console.log('accumulator:', acc)
  console.log('currentValue:', currentValue)
  console.log('currentIndex:', currentIndex)
  console.log('array:', array)
  return acc + currentValue;
}); // 25
console.log(total);

四、filter(fn) 方法

array.filter(function(element, [index], [array]){ ... }, [thisArg])

filter(fn) 用于把 Array 的某些元素过滤掉,然后返回剩下的元素,它同样接收一个函数 fn 函数作用参数,当 filter 循环一个数组时,会把当前元素、当前元素的索引、整个数组集合作为fn函数的三个参数传递给 fn 函数,经 fn 函数处理后返回一个新的数组。

let arr = [1, 2, 4, 5, 6, 9, 10, 15];
let r = arr.filter(function (element, index, array) {
  console.log('element: ', element);
  console.log('index: ', index);
  console.log('array: ', array);
    return element % 2 !== 0;
});
console.log(r); // [1, 5, 9, 15]

可见用filter()这个高阶函数,关键在于正确实现一个“筛选”函数。

利用filter,可以巧妙地去除Array的重复元素:

let arr = ['apple', 'strawberry', 'banana', 'pear', 'apple', 'orange', 'orange', 'strawberry'];
let r = arr.filter(function (element, index, self) {
    return self.indexOf(element) === index;
});

👍 去除重复元素依靠的是 indexOf 总是返回第一个元素的位置,后续的重复元素位置与 indexOf 返回的位置不相等,因此被 filter 滤掉了。