我是靠谱客的博主 着急小虾米,这篇文章主要介绍js小记:filter()、forEach()、map()、reduce()、reduceRight()的区别,现在分享给大家,希望可以做个参考。

一、简述

ECMAScript 5为数组定义了5个迭代方法。每个方法都接收两个参数:要在每一项上运行的函数和(可选的)运行该函数的作用域对象。
传入这些方法中的函数会接收三个参数:数组项的值、该项在数组中的位置和数组对象本身。根据使用的方法不同,这个函数执行后的返回值可能会也可能不会影响访问的返回值。以下是这5个迭代方法的作用。

  • every():对数组中的每一项运行给定函数,如果该函数对每一项都返回 true ,则返回 true。
  • some():对数组中的每一项运行给定函数,如果该函数对任一项返回 true ,则返回 true
  • filter():对数组中的每一项运行给定函数,返回该函数会返回 true 的项组成的数组。
  • forEach():对数组中的每一项运行给定函数。这个方法没有返回值。
  • map():对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。

他们的参数都一样:

  • 在每一项上运行的函数(该函数有三个参数)
    • 函数第一个参数:数组项的值
    • 函数第二个参数:数组项的索引
    • 函数第三个参数:数组对象本身
  • 运行该函数的作用域对象——影响this的值(可选)

二、区别

filter()、forEach()、map()、some()、every()都是对数组的每一项调用函数进行处理。

  • 区别:
    – some()、every()的返回值 :true / false
    – filter()、map()的返回值 :一个新数组
    – forEach()无返回值。

使用filter()、forEach()、map()、some()、every()都不改变原数组。


下面进入正题,用例子区分一下filter()、forEach()、map()间的区别:

  • filter()
复制代码
1
2
3
4
5
6
7
var arr = [1,2,3,4]; var my = arr.filter(function(item,index,arr){ return item*2 > 2; }); console.log(my); //[2, 3, 4] //说明filter返回 true的项组成的数组 console.log(arr); //[1, 2, 3, 4]
复制代码
1
2
3
4
5
6
7
var arr = [1,2,3,4]; var my = arr.filter(function(item,index,arr){ return item*2; }); console.log(my); //[1, 2, 3, 4] //说因为每一项都为true console.log(arr); //[1, 2, 3, 4]
  • forEach()
复制代码
1
2
3
4
5
6
7
var arr = [1,2,3,4]; var my = arr.forEach(function(item,index,arr){ return item*2; }); console.log(my); //undefined //说明forEach方法没有返回值 console.log(arr); //[1, 2, 3, 4]
  • map()
复制代码
1
2
3
4
5
6
7
var arr = [1,2,3,4]; var my = arr.map(function(item,index,arr){ return item*2; }); console.log(my); //[2, 4, 6, 8] console.log(arr); //[1, 2, 3, 4]

三、forEach() 与 map()

细讲下forEach() 与 map()的区别:
map()会分配内存空间存储新数组并返回,forEach()不会返回数据但可以改变原数组。

1、forEach()
forEach适合于你并不打算改变数据的时候,而只是想用数据做一些事情 – 比如存入其他变量中 或 打印出来。

复制代码
1
2
3
4
5
6
7
8
9
let arr = ['a', 'b', 'c', 'd']; arr.forEach((letter) => { console.log(letter); }); // a // b // c // d

当然forEach也可以改变原数组:

复制代码
1
2
3
4
5
6
var arr = [1,2,3,4,5]; arr.forEach((num, index) => { return arr[index] = num * 2; }); console.log(arr) //[2, 4, 6, 8, 10]

2、map()
map()适用于你要改变数据值的时候,返回一个新的数组。这样的优点在于你可以使用复合(composition)(map(), filter(), reduce()等组合使用)来玩出更多的花样。

复制代码
1
2
3
4
let arr = [1, 2, 3, 4, 5]; let arr2 = arr.map(num => num * 2).filter(num => num > 5); console.log(arr2) // [6, 8, 10]

四、reduce()、reduceRight()

数组还有两个归并方法:reduce()、reduceRight()
reduce()方法从左到右遍历数组;而reduceRight()从右到左遍历数组;

reduce()、reduceRight()的参数一样:

  • 第一个参数:在每一项调用的函数(该函数包含四个参数)
    • 函数第一个参数:前一项的值
    • 函数第二个参数:当前项的值
    • 函数第三个参数:项的索引
    • 函数第四个参数:数组对象
  • 第二个参数:作为归并的基础值(可选)

reduce()、reduceRight()的第一个参数是个函数,该函数`返回的任何值都会作为第一个参数 自动传给下一项`。为了归并,所以它们都是把数组的第一项和第二项作为第一次遍历。(也就是说:假如数组有n个元素,那它调用reduce()或reduceRight()后 就是遍历 n-1 次) 如果不懂可以看下面例子。

例1:

复制代码
1
2
3
4
5
6
var a = [1,2,3].reduce(function(prev,item,key,array){ console.log(9); //打印了 两次9 return prev+item; }); console.log(a);//6

输出:9 9 6

我们看看发生了什么,首先进行第一次归并:将数组的第一项与第二项相加(即1+2),将结果3作为函数的第一个参数传给下一项;然后进行第二次归并:用3+3,最终返回6。其间由于进行了两次归并,所以在输出6之前,会输出两次9.

复制代码
1
2
3
4
5
6
7
8
9
10
11
var a = [1,2,3].reduce(function(prev,item,key,array){ console.log(prev,item,key,array); return prev+item; }); console.log(a); //输出: //1 2 1 [1, 2, 3] //3 3 2 [1, 2, 3] //6
复制代码
1
2
3
4
5
6
7
8
9
10
var a = [1,2,3].reduce(function(prev,item,key,array){ console.log(prev,item,key,array); }); console.log(a); //输出: //1 2 1 [1, 2, 3] //undefined 3 2 [1, 2, 3] //undefined

那如果这个数组只有一项或是个空数组呢?我们往下看:

例2:

复制代码
1
2
3
4
5
6
7
var a = [1].reduce(function(prev,item,key,array){ console.log(2); //不打印 return prev+item; }); console.log(a);//1 //如果归并的数组为空,则会报错

输出:1

没有打印2,直接输出1,说明reduce的函数压根没执行,直接将原数组返回了。
如果这个数组是空的,调用reduce() 或 reduceRight()后会直接报错,所以我们在进行上面操作时最好判断下是否为空数组,不为空再做处理。


例3:
数组有n个元素,如果传入了归并的基础值,则遍历 n 次

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
var a = [1,2,3].reduce(function(prev,item,key,array){ console.log(prev,item,key,array); return prev+item; }, 0); console.log(a); //输出: //0 1 0 [1, 2, 3] //1 2 1 [1, 2, 3] //3 3 2 [1, 2, 3] //6

reduce应用

什么时候用reduce?


只要满足下面两点就可以用reduce

  • 对数组进行处理
  • 最终返回一个值(这个值可以是Number、Array、Object等等)

1、清洗或加工数据

例如有数组list

复制代码
1
2
3
4
5
6
7
const list = [ { name: 'sam', age: 11 }, undefined, { name: '', age: 12 }, { name: 'amy', age: 18 } ];

需求1: 过滤掉list数组中所有为空,以及当前项的name值为空的数据

复制代码
1
2
3
4
5
6
7
8
9
10
function getNewList(arr) { return arr.reduce((prev, item) => { if (!item || !item.name) return prev; return prev.concat(item); }, []); } console.log(getNewList(arr)); // [ {"name":"sam","age":11}, {"name":"amy","age":18}]

需求2: 过滤掉list数组中所有为空,以及当前项的name值为空的数据,并将改变过滤后数据的格式

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function getNewList(arr) { return arr.reduce((prev, item) => { if (!item || !item.name) return prev; const obj = { hello: `I am ${item.name}` }; return prev.concat(obj); }, []); } console.log(getNewList(arr)); // [{"hello":"I am sam"},{"hello":"I am amy"}]

需求3: 过滤掉list数组中所有为空,以及当前项的name值为空的数据,最后输出一个以{name: age}为格式的对象

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
function getNewObj(arr) { return arr.reduce((prev, item) => { if (!item || !item.name) return prev; prev[item.name] = item.age; return prev; }, {}); } console.log(getNewObj(arr)); // {"sam":11,"amy":18}

最后

以上就是着急小虾米最近收集整理的关于js小记:filter()、forEach()、map()、reduce()、reduceRight()的区别的全部内容,更多相关js小记:filter()、forEach()、map()、reduce()、reduceRight()内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(136)

评论列表共有 0 条评论

立即
投稿
返回
顶部