JS的数组可以调用操作数组的高阶函数来方便对数组元素进行选择和遍历,高阶函数都封装了遍历数组的功能,以代替传统的for循环。
高阶函数需要传入一个回调函数,在回调函数中执行方法体,回调函数的参数就是每一次遍历中数组的元素,高阶函数会自动将数组元素传入回调函数,并且所有高阶函数的返回值都是一个新的数组,需要新建数组来接收返回值(下同)
1.filter()函数 (在使用时我更喜欢说方法,java的习惯)
介绍:过滤函数人如其名是用来过滤数组中的元素的,该函数需要传入一个回调函数即一个匿名函数,filter函数会遍历数组中的所有元素,且每遍历一次就将该元素传入匿名函数。
要求:filter()函数必须传入一个匿名函数,且这个匿名函数的返回值必须是一个布尔值 (true或flase),如果为true则将该元素返回到新的数组,反之则舍弃
使用:
//高阶函数都封装了遍历数组的功能,经常使用来代替常规的for循环遍历
let arr = [0,3,4,1,22,52,5];
//1.filter函数,过滤数组中特定的元素,它会返回一个新的数组。例:过滤所有大于4的数
//高阶函数需要传入一个回调函数,在回调函数中执行方法体,回调函数的参数就是每一次遍历中数组的元素,高阶函数会自动将数组元素传入回调函数(下同)
//回调函数必须返回一个布尔值,如果为true则将该元素返回到新的数组,反之则舍弃
let arr2 = arr.filter(function (n) {
return n>4 ;
});
console.log(arr2); //输出 22 52 5
2.map()函数 ,映射函数 f(x)=x中的f
介绍:f就是x和y之间的映射关系,map也是,用来将数组中的每一个元素进行特定的变换后返回一个新的数组
要求:需要回调函数,map函数需要返回一个数,这个返回的数会加入新的数组
使用:
//2.map函数,映射函数,就像数学里的函数f(x)=x一样 f就是x和y之间的映射关系,map也是,用来将数组中的每一个元素进行特定的变换后返回一个新的数组
//回调函数需要返回一个数,这个数将被加入新的数组,例:将数组中所有的元素乘2之后返回。
let arr = [0,3,4,1,22,52,5];
let arr3 = arr.map(function (n) {
return n*2;
});
console.log(arr3);
3.reduce()函数 ,累积函数
介绍:用来来对数组中的元素进行累计,如累加,累乘,相减等,三个高阶函数中较复杂的一个。
要求:reduce函数有两个参数,第一个是回调函数,第二个是回调函数的第一个参数的缺省值,对于整形数组这种可以直接进行计算的不给缺省值则默认为第一个值,所以可以省略不写。**但如果是对象数组,则缺省值就是第一个对象,对象无法直接计算,所以会报错。
回调函数可以有四个参数
1.上一次遍历中回调函数的返回值previousValue
2.当前次遍历中的数组元素currentValue
3.当前次遍历中的数组下标currentIndex
4.调用reduce函数的数组本体 array (这里就是arr)
arr.reduce(function (previousValue, currentValue, currentIndex, array) {
return array[0] + currentValue + previousValue
},initalValue);
其中第一遍循环中的默认值由reduce函数的第二个参数initalValue给出,若不写则默认为数组的第一个元素,如果数组中是对象的话,不写initalValue容易报错。
人话:reduce的第一个参数就是保留了上一次遍历的计算返回值,方便累计。
使用:
//3.reduce函数,集合函数,用来对数组中的元素进行累计,如累加,累乘,相减等,三个高阶函数中较复杂的一个。
//reduce函数有两个参数,第一个是回调函数,第二个是回调函数的第一个参数的默认值。
//回调函数有两个参数,第一个为previousValue,即上一次遍历中回调函数返回的值,其第一遍循环中的默认值由reduce函数的第二个参数initalValue给出,若不写则默认为0,第二个即为这一次遍历中的数组元素
//是不是有点绕? 但其实很简单,就是保留了上一次遍历的计算,方便累计,例:求数组的和
let arr4 = arr.reduce(function (preValue,currentValue) {
return preValue + currentValue
},0);
console.log(arr4);
4.高级用法:链式调用,箭头函数
高阶函数的链式调用
说明:和java流操作一样,对于一个返回值是特定类型(可能是数组,对象等等)的方法,可以在该方法后面继续以 . 来调用其他方法,链式的一次性执行所有需要的操作,然后返回最终的值。
实例:将上面三个高阶函数的要求集合在一个式子里。
//高阶函数的链式调用,一次性满足三个条件
let arr5 = arr.filter(function (n) {
return n>4;
}).map(function (n) {
return n*2;
}).reduce(function (previousValue, currentValue) {
return currentValue + previousValue
},0);
console.log(arr5);
箭头函数
介绍:箭头函数实际上是匿名函数的语法糖,用于简化函数写法(匿名函数与java匿名方法类似,都是没有对象声明的)
使用:=> 即为箭头 ** 箭头左边为形参,箭头右边为函数返回值 (即return)**,若外部函数能自动传参进入匿名函数则可以使用箭头函数简化匿名函数的写法,如果匿名函数方法体较为复杂,还是不建议用箭头。
实例:改写链式调用中的代码,使其为箭头函数。
//箭头函数,改写上述代码
let arr6 = arr.filter(n => n>4).map(n => n*2).reduce((preValue,n) => preValue+n);
//这里的reduce不需要第二个参数的原因是,该数组元素是整形可以直接计算,但如果数组元素是对象,则默认值就是数组中的第一个对象,如果不手动赋予初始值,则直接使用是会报错,或者NaN未找到。