数组的遍历方法有哪些

127 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第17天,点击查看活动详情

数组的遍历方法有哪些

方法是否改变原数组特点
forEach()取决于元素的数据类型数组方法,没有返回值,是否会改变原数组取决于数组元素的类型是基本类型还是引用类型,详细解释可参考文章:《forEach到底可以改变原数组吗》
map()数组方法,不改变原数组,有返回值,可链式调用
filter()数组方法,过滤数组,返回包含符合条件的元素的数组,可链式调用
for...offor...of遍历具有Iterator迭代器的对象的属性,返回的是数组的元素、对象的属性值,不能遍历普通的obj对象,将异步循环变成同步循环
every() 和 some()数组方法,some()只要有一个是true,便返回true;而every()只要有一个是false,便返回false.
find() 和 findIndex()数组方法,find()返回的是第一个符合条件的值;findIndex()返回的是第一个返回条件的值的索引值
reduce() 和 reduceRight()数组方法,reduce()对数组正序操作;reduceRight()对数组逆序操作

遍历方法的详细解释:《细数JavaScript中那些遍历和循环》

11.1. js for 循环注意点

 for (var i = 0, j = 0; i < 5, j < 9; i++, j++) {
   console.log(i, j);
 }
 ​
 // 当判断语句含有多个语句时,以最后一个判断语句的值为准,因此上面的代码会执行 10 次。
 // 当判断语句为空时,循环会一直进行。

11.2. for...in和for...of的区别

for…of 是ES6新增的遍历方式,允许遍历一个含有iterator接口的数据结构(数组、对象等)并且返回各项的值,和ES3中的for…in的区别如下

  • for…of 遍历获取的是对象的键值,for…in 获取的是对象的键名;
  • for… in 会遍历对象的整个原型链,性能非常差不推荐使用,而 for … of 只遍历当前对象不会遍历原型链;
  • 对于数组的遍历,for…in 会返回数组中所有可枚举的属性(包括原型链上可枚举的属性),for…of 只返回数组的下标对应的属性值;

总结: for...in 循环主要是为了遍历对象而生,不适用于遍历数组;for...of 循环可以用来遍历数组、类数组对象,字符串、Set、Map 以及 Generator 对象。

11.3. 如何使用for...of遍历对象

for…of是作为ES6新增的遍历方式,允许遍历一个含有iterator接口的数据结构(数组、对象等)并且返回各项的值,普通的对象用for..of遍历是会报错的。

如果需要遍历的对象是类数组对象,用Array.from转成数组即可。

 var obj = {
     0:'one',
     1:'two',
     length: 2
 };
 obj = Array.from(obj);
 for(var k of obj){
     console.log(k)
 }

如果不是类数组对象,就给对象添加一个[Symbol.iterator]属性,并指向一个迭代器即可。

 //方法一:
 var obj = {
     a:1,
     b:2,
     c:3
 };
 ​
 obj[Symbol.iterator] = function(){
     var keys = Object.keys(this);
     var count = 0;
     return {
         next(){
             if(count<keys.length){
                 return {value: obj[keys[count++]],done:false};
             }else{
                 return {value:undefined,done:true};
             }
         }
     }
 };
 ​
 for(var k of obj){
     console.log(k);
 }
 ​
 ​
 // 方法二
 var obj = {
     a:1,
     b:2,
     c:3
 };
 obj[Symbol.iterator] = function*(){
     var keys = Object.keys(obj);
     for(var k of keys){
         yield [k,obj[k]]
     }
 };
 ​
 for(var [k,v] of obj){
     console.log(k,v);
 }

在异步中的使用

 function muti(num) {
     return new Promise(resolve=>{
         setTimeout(()=>{
             resolve(num*num)
         },1000)
     })
 }
 const nums =[1,2,3]
 nums.forEach(async (i)=>{
     const res = await muti(i)
     console.log(res)
 })
 ​
 !(async function(){
     for(let i of nums){
         const result = await muti(i)
         console.log(result)
     }
 })()

11.4. forEach和map方法有什么区别

这方法都是用来遍历数组的,两者区别如下:

  • forEach()方法会针对每一个元素执行提供的函数,该方法没有返回值,是否会改变原数组取决于数组元素的类型是基本类型还是引用类型,详细解释可参考文章:《forEach到底可以改变原数组吗》
  • map()方法不会改变原数组的值,返回一个新数组,新数组中的值为原数组调用函数处理之后的值;