JS中循环遍历数组的几种常用方式总结

890人浏览 / 0人评论 / 添加收藏

第一种:for循环,也是最常见的 
最简单的一种,也是使用频率最高的一种,虽然性能不弱,但仍有优化空间

const arr = [11, 22, 33, 44, 55, 66, 77, 88]; 
for (let i = 0; i < arr.length; i++) { 
     console.log(arr[i]); 
   } 
打印结果:


第二种:优化版for循环 
const arr = [11, 22, 33, 44, 55, 66, 77, 88]; 
for (let i = 0; len < arr.length; i < len; i++) { 
     console.log(arr[i]); 
   } 
简要说明:使用临时变量,将长度缓存起来,避免重复计算数组长度,当数组较大时优化效果才会比较明显 
这种方法基本上是所有循环遍历方法中性能最高的一种

第三种:forEach()
对于forEach方法除非使用try/catch,否则无法中途停止循环,break或者return都无法使循环中途停止。而for…of循环可以与break,continue和return配合使用,中途停止循环: 
1.)forEach() 遍历普通数组

const arr = [11, 22, 33, 44, 55, 66, 77, 88]; 
arr.forEach(item => { 
     //forEach循环 
     console.log(item); 
   }); 
打印结果:


2.)forEach() 遍历对象类型数组

const arrObj = [ 
     { 
       id: 1, 
       name: "张三" 
     }, 
     { 
       id: 2, 
       name: "李四" 
     }, 
     { 
       id: 3, 
       name: "王五" 
     } 
   ]; 
arrObj.forEach(item => { 
  console.log(item.id + "-------" + item.name); 
}); 
打印结果:

简要说明: 数组自带的foreach循环,使用频率较高,实际上性能比普通for循环弱

第四种:map() 
定义和用法

1. map即是 “映射”的意思 ,原数组被“映射”成对应新数组 
2. map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。 
3. map() 不会改变原始数组。 
4. map() 不会对空数组进行检测。 
5. map支持return


const arr = [11, 22, 33, 44, 55, 66, 77, 88]; 
var newArr = arr.map((value, index) => { 
     console.log(value + "----" + index); 
     return value * 10; 
   }); 
console.log(newArr); 
打印结果:

简要说明: 这种方式也是用的比较广泛的,虽然用起来比较优雅,但实际效率还比不上foreach

forEach()和map()区别:

forEach()和map()方法通常用于遍历Array元素 
forEach:返回undefined;用来遍历数组中的每一项,不影响原数组 
map:返回一个包含已转换元素的新数组;支持return,相当于与原数组克隆了一份,把克隆的每项改变了,也不影响原数组 
 

第五种:filter遍历 
定义和用法

filter用于对数组进行过滤。 
filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。 
filter() 不会对空数组进行检测;不会改变原始数组 
语法

array.filter(function(currentValue,index,arr), thisValue) 
let arr = [56, 15, 48, 3, 7];

let newArr = arr.filter(function (value, index, array) { 
   return value % 2 === 0; 
});

console.log(newArr) 
// [56, 48] 

第六种:for…of 方法 
作为ES6新增的循环方法,个人觉得相当好用,而且方便。这个方法避开了for-in循环的所有缺陷。而且,它可以正确响应break、continue和return语句。

//循环数组 
let arr = ['123','qwewq','sfds']; 
for(let item of arr){ 
   console.log(item);    //item指的的就是数组每一项的值。不是索引。 

//输出 
//'123' 
//'qwewq' 
//'sfds' 

for-of循环不仅支持数组,还支持大多数类数组对象,例如DOM NodeList对象。但是for of也有一个致命伤,就像例子看到的,没有索引。对,这是优点也是缺点。遍历数组对象,直接就是item.属性(或者item[属性]),而不用像for循环那样arr[index].属性(arrindex)。但是你有的时候真的就得用到index。不好意思,只能把数组转成Map()。但我觉得真的需要用到index,还是换成forEach吧。

简要说明: 这种方式是es6里面用到的,性能要好于forin,但仍然比不上普通for循环

第七种:for…in 方法 
for in循环是用来遍历对象的。要知道JavaScript对象的所有属性都是字符串,不过属性对应的值可以是任意数据类型。(注意:遍历时不仅能读取对象自身上面的成员属性,也能遍历出对象的原型属性)

语法

let obj = {a:1, b:2, c:3}; 
for (let prop in obj) {    //prop指对象的属性名 
console.log(prop, obj[prop]); 

// 输出: 
// a,1 
// b,2 
// c,3 

for in同样可以用来循环数组,但是不推荐这么做。由于Array也是对象,而它的每个元素的索引被视为对象的属性,因此,for in循环可以直接循环出Array的索引,但得到的是String而不是Number,所以一旦你想用这个index去进行计算,就会出错。而且因为会遍历原型属性,所以可能得出的结果不会是你想要的(具体细节不多说,需要了解的自己查询,反正很多坑)。虽然可以用hasOwnProperty()方法避免这个缺陷,但是何必呢,循环方法那么多,换一个就是了。

for (var index in myArray) { // 不推荐这样 
console.log(myArray[index]); 


为什么用for … in?

简要说明: 这个循环很多人爱用,但实际上,经分析测试,在众多的循环遍历方式中 
它的效率是最低的

关于for …of和for …in区别 
https://blog.csdn.net/weixin_42695446/article/details/84531600

第八种:find方法 
遍历数组,找到第一个符合条件的项,并返回该项;不会继续遍历数组;否则返回undefined 
不会改变数组 
[1,4,-5,10].find((n) => n < 0 ) 
//-5 

上面代码找出数组中第一个小于0的成员

[1,5,10,15].find(function(value,index,arr){ 
return value > 9 
}) 
//10 

上面代码中,find方法的回调函数可以接受三个参数,依次为当前的值、当前的位置和原数组。

第九种:findIndex方法 
遍历数组找到第一个符合条件的项,并返回该项的索引值;不会继续遍历数组;否则返回-1。 
不会改变数组 
[1,5,10,15].findIndex(function(value,index,arr){ 
return value > 9 
}) 
findIndex() 当中的回调函数也是接收三个参数,与find() 相同。

 

第十种:Array.some() 方法 
1)如果有一个元素满足条件,则表达式返回true,剩余的元素不会再执行检测。 
2)如果没有满足条件的元素,则返回false。 
3)返回值是布尔值 
注意:

1) some() 不会对空数组进行检测。 
2) some() 不会改变原始数组。 
var ages = [3, 18, 17, 16] 
var checkoutVal = function checkout (age) { 
  console.log(age >= 18) // false true  有一个满足条件的会停止检测剩余的元素 
  return age >= 18 

console.log(ages.some(checkoutVal)) // true 
let someArr = [2,3,4]; 
let someResult = someArr.some((item, index)=>{ 
 return item > 3 
}); 
console.log(someResult); 
// 结果为: true 


第十一种:Array.every() 方法 (所有的,每一个) 
1)如果数组中有一个元素不满足,则整个表达式返回false;且剩余的元素不会再进行检测 
2)如果所有元素都满足条件,则返回true。 
3)返回值是布尔值 
注意:

1) some() 不会对空数组进行检测。 
2) some() 不会改变原始数组。 
 var ages = [3, 18, 17, 16] 
 const fn = (currentValue) => currentValue < 40 
 console.log(ages.every(fn)) // true  值全都符合函数条件 
let everyArr = [2,3,4]; 
let everyResult = everyArr.every((item, index)=>{ 
 return item > 0 
}); 
console.log(everyResult); 
// 结果为: true 
Array.some() 和Array.every() 的区别???

 

第十二种:reduce() 方法 
1)接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始缩减,最终为一个值。 
2)第二个参数作为第一次调用的a的值 
// reducer 
let reduceArr = [0,1,2,3,4] 
let reduceResult = reduceArr.reduce((a, b)=>{ 
 return a + b; 
}); 
console.log(reduceResult); 
// 结果: 10 
上述列举了几种方式都有一一做过对比分析,基本上可以得出的结论是: 
普通for循环才是最优雅的,优化后的for循环最快

注意: 
数组方法无法中途停止循环,所以都不可以使用break和continue; 
for循环之类的不可以return,但是能正常使用break和continue; 
 

 

全部评论