遍历数组方法
一、数组遍历方法
1.forEach()
forEach()
方法用于调用数组的每个元素,并将元素传递给回调函数。数组中的每个值都会调用回调函数。语法如下:
array.forEach(function(currentValue,index,arr),thisValue)
该方法的第一个参数为回调函数,是必传的,它有三个参数:
- currentValue :必须。当前元素
- index:可选。当前元素的索引值
- arr:可选。当前元素所属的数组对象
let arr=[1,2,3,4,5]
arr.forEach((item,index,arr)=>{
console.log(index+':'+item)
})
该方法还可以有第二个参数,用来绑定回调函数内部的this变量(前提是回调函数不能是箭头函数,因为箭头函数没有this)
let arr=[1,2,3,4,5]
let arr1=[9,8,7,6,5]
arr.forEach(function(item,index,arr){
console.log(this[index]) //9 8 7 6 5
},arr1)
⚠️:
forEach
方法不会改变原数组,也没有返回值forEach
方法无法使用break,continue跳出循环,使用return时,效果和在for循环中使用continue一致forEach
方法无法遍历对象,仅适用于数组的遍历
2.map()
map()
方法会返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。该方法按照原始数组元素顺序依次处理元素。语法如下:
array.map(function(currentValue,index,arr),thisValue)
该方法的第一个参数为回调函数,是必传的,它有三个参数:
- currentValue:必须。当前元素的值
- index:可选。当前元素的索引值
- arr:可选。当前元素属于的数组对象
let arr=[1,2,3]
arr.map(item=>{
return item+1 //[2,3,4]
})
该方法的第二个参数用来绑定参数函数内部的this变量,是可选的:
let arr=['b','c']
[1,2].map(function(e){
return this[e] //['b','c']
},arr)
该方法还可以链式调用:
let arr=[1,2,3]
arr.map(item=>item+1).map(item=>item+1) //[3,4,5]
⚠️:
map
方法不会对空数组进行检测map
方法遍历数组时会返回一个新数组,不会改变原始数组map
方法有返回值,可以return出来,map的回调函数中支持return返回值map
方法无法遍历对象,仅适用于数组的遍历
3.for…of
for...of
语句创建一个循环来迭代可迭代的对象。在ES6中引入的for...of
循环,以替代for...in
和forEach()
,并支持新的迭代协议。for...of
允许遍历Arrays(数组),String(字符串),Maps(映射),Sets(集合)等可迭代的数据结构等。语法如下:
for (variable of iterable){
statement
}
该方法有两个参数:
- variable:每个迭代的属性值被分配给该变量。
- iterable:一个具有可枚举属性并且可以迭代的对象。
let a=['a','b','c']
let s=new Set(['A','B','C'])
let m=new Map([[1,'x'],[2,'y'],[3,'z']])
for (let x of a){ //遍历数组
console.log(x) //'a' 'b' 'c'
}
for (let x of s){ //遍历set
console.log(x) //'A' 'B' 'C'
}
for (let x of m){ //遍历map
console.log(x) //1='x' 2='y' 3='z'
}
⚠️:
for...of
方法只会遍历当前对象的属性,不会遍历其原型链上的属性for...of
方法适用遍历数组/类数组/字符串/map/set等拥有迭代器对象的集合for...of
方法不支持遍历普通对象,因为其没有迭代器对象。如果想要遍历一个对象的属性,可以用for…in 方法- 可以使用break、continue、return来中断循环遍历
4.filter()
filter()
方法用于过滤数组,满足条件的元素会被返回。它的参数是一个回调函数,所以数组元素依次执行该函数,返回结果为true的元素会被返回,如果没有符合条件的元素,则返回空数组。语法如下:
array.filter(function(currentValue,index,arr),thisValue)
该方法的第一个参数为回调函数,是必传的,它有三个参数:
- currentValue:必须。当前元素的值
- index:可选。当前索引的值
- arr:可选。当前元素属于的数组对象
const arr=[1,2,3,4,5]
arr.filter(item=>item>2) //[3,4,5]
同样,它也有第二个参数,用来绑定参数函数内部的this变量。
可以使用filter()方法来移除数组中的undefined、null、NaN等值
let arr=[1,undefined,2,null,3,false,'',4,0]
arr.filter(Boolean)
⚠️:
filter()
方法会返回一个新的数组,不会改变原数组filter()
方法不会对空数组进行检测filter()
方法仅适用于检测数组
5.some()、every()
some()
方法会对数组的每一项进行遍历,只要有一个元素符合条件,就返回true,且剩余的元素不会再进行检测,否则就返回false。
every()
方法会对数组中的每一项进行遍历,只有所有元素都符合条件时,才返回true,如果数组中检测到一个元素不满足,则整个表达式返回false,且剩余的元素不会再进行检测。语法如下:
array.some(function(currentValue,index,arr),thisValue)
array.every(function(currentValue,index,arr),thisValue)
两个方法的第一个参数为回调函数,是必传的,它有三个参数:
- currentValue:必须。当前元素的值
- index:可选。当前元素的索引值
- arr:可选。当前元素属于的数组对象
let arr=[1,2,3,4,5]
arr.some(item=>item>4) //true
arr.every(item=>item>0) //true
⚠️:
- 两个方法都不会改变原数组,会返回一个布尔值
- 两个方法都不会对空数组进行检测
- 两个方法都仅适用于检测数组
6.reduce()、reduceRight()
reduce()
方法会为数组中的每个值(从左到右)开始缩减,最终计算为一个值。reduce()
可以作为一个高阶函数,用于函数的compose。语法如下:
array.reduce(function(total,currentValue,currnetIndex,arr),initialValue)
reduce()
方法会为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,回调函数接受四个参数:
- total:上一次调用回调返回的值,或者是提供的初始值(initialValue)
- currentValue:当前被处理的元素
- currentIndex:当前元素的索引
- arr:当前元素所属的数组对象
该方法的第二个参数是initialValue,表示传递给函数的初始值(作为第一次调用callback的第一个参数):
let arr=[1,2,3,4]
let sum=arr.reduce((prev,cur,index,arr)=>{
console.log(prev,cur,index). //1,2,1
//3,3,2
//6,4,3
return prev+cur
})
console.log(arr,sum) //[1,2,3,4] //10
再加一个初始值:
let arr=[1,2,3,4]
let sum=arr.reduce((prev,cur,index,arr)=>{
console.log(prev,cur,index). //5,1,0
//6,2,1
//8,3,2
//11,4,3
return prev+cur
},5)
console.log(arr,sum) //[1,2,3,4] //15
由此可以得出结论:如果没有提供初始值initialValue,reduce会从索引1的地方开始执行callback方法,跳过第一个索引。如果提供了初始值initalValue,从索引0开始执行。
reduceRight()
方法和reduce()
用法几乎一致,只是该方法是对数组进行倒序遍历的,而reduce()是正序遍历的
let arr=[1,2,3,4]
let sum=arr.reduceRight((prev,cur,index,arr)=>{
console.log(prev,cur,index) //5,4,3
//9,3,2
//12,2,1
//14,1,0
return prev+cur
},5)
console.log(arr,sum) //[1,2,3,4] //15
⚠️:
- 这两个方法都不会改变原数组
- 这两个方法如果添加初始值,就会改变原数组,会将这个初始值放在数组的第一位
- 这两个方法对于空数组是不会执行回调函数的
7.find()、findIndex()
find()
方法通过函数内的判断的数组的第一个元素的值。当数组中的元素在测试条件时返回true时,find()
返回符合条件的元素,之后的值不会再调用执行函数。如果没有符合条件的元素返回undefined。
findIndex()
方法返回传入一个测试函数符合条件的数组第一个元素的位置(索引)。当数组中的元素在函数条件时返回true时,findIndex()
返回符合条件的元素的索引位置,之后的值不会再调用执行函数。如果没有符合条件的元素返回-1。语法如下:
array.find(function(currentValue,index,arr),thisValue)
array.findIndex(function(currentValue,index,arr),thisValue)
两个方法的第一个参数为回调函数,是必传的,它有三个参数:
- currentValue:必须。当前元素
- index:可选。当前元素的索引
- arr:可选。当前元素所属的数组对象
let arr=[1,2,3,4,5]
arr.find(item=>item>2) //3
arr.findIndex(item=>item>2) //2
⚠️:
- find():返回的是第一个符合条件的值
- findIndex():返回的是第一个返回条件的值的索引值
- 两个方法对于空数组、函数是不会执行的
- 两个方法都不会改变原数组
8.keys()、values()、entries()
三个方法都返回一个数组的迭代对象,对象的内容不太相同:
keys()
:返回数组的索引值values()
:返回数组的元素entries()
:返回数组的键值对
语法如下:
array.keys()
array.values()
array.entries()
三个方法都没有参数:
let arr=['a','b','c']
const iterator1=arr.keys()
const iterator2=arr.values()
const iterator3=arr.entries()
for (let item of iterator1){
console.log(item) //0 1 2
}
for (let item of iterator2){
console.log(item) //a b c
}
for (let item of iterator3){
console.log(item) //[0,'a'] [1,'b'] [2,'c']
}