JS 数组和对象的遍历方式, 以及几种方式的比较

265 阅读3分钟

「这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战

1.for…in…

特点:可枚举对象

const person = {
    name: 'Lydia',
    age: 21,
  };
  
  for (const item in person) {
    console.log(item); //name  age
  }

这个输出结果很简单name age

对于这个结果可以简单理解为,对于对象object,使用for…in…循环是对对象的key值进行循环

但是如果for in的是一个数组

// for (const item in arr) {
//   console.log(item);
//   console.log(arr[item]);
// }
打印输出:
0
a
1
b
2
c

可以看出使用for…in…是输出索引值,通过索引值能拿到数组数据

可枚举数组的原型对象

Array.prototype.sayHello = function(){
    console.log("Hello")
  }
  Array.prototype.str = 'world';
  var myArray = [1,2,3];
  myArray.name='数组';
  
  for(let index in myArray){
    console.log(index);
  }

这个输出结果是: 0 1 2 name sayHello str

这个结果看出for in 不仅返回的是数组的下标,而且将数组的原型对象以及数组对象本身属性值都会返回。但是这也存在一个问题,在实际工作开发中,这些对象很可能是不需要的,全部列举出来可能会产生新的问题。

可以使用hasOwnProperty解决这个问题

Array.prototype.sayHello = function(){
    console.log("Hello")
  }
  Array.prototype.str = 'world';
  var myArray = [1,2,3];
  myArray.name='数组';
  
  for(let index in myArray){
    if(myArray.hasOwnProperty(index)) {
      console.log(index);
    }
  } //打印
            0
            1
            2
            name

2.for…of…

const person = {
    name: 'Lydia',
    age: 21,
  };
  
  for (const item of person) {
      console.log(item);
    }

这里会很神奇得打印报错:person is not iterable

原因是什么呢?for…of…不能对对象进行循环

对数组:

 const arr = ['a','b','c']
 
 for (const item of arr) {
    console.log(item);
  }
打印这个输出结果为 ‘a’ ‘b’ ‘c’

这个结果看出使用for…of…是输出数组值

for of的作用:

Array.prototype.sayHello = function(){
  console.log("Hello")
}
Array.prototype.str = 'world';
var myArray = ['a','b','c'];
myArray.name='数组';

for(let index of myArray) {
  console.log(index)
}

for of的作用同样是可以输出索引值和数组值,而且不会输出数组的原型对象。

并且可以被中断!

var arr = [3, 5, 7];

for (let value of arr) {
  console.log(value);
  if (value == 5) {
    break;
  }
}

3.forEach

const person = {
  name: 'Lydia',
  age: 21,
}

person.forEach((i) => {
  console.log(i)
})
打印:TypeError: person.forEach is not a function

显然forEach不能对对象进行遍历

forEach的作用

Array.prototype.sayHello = function(){
    console.log("Hello")
  }
  Array.prototype.str = 'world';
  var myArray = ['a','b','c'];
  myArray.name='数组';
  
  myArray.forEach((value,i) => {
    console.log(value)
    console.log(i)
  })
  打印:
  a
0
b
1
c
2

输出的结果是 ‘a’ 0 ‘b’ 1 ‘c’ 2

使用forEach可以输出索引值和数组值,而且不会输出数组的原型对象。

forEach无法break

var arr = [3, 5, 7];

arr.forEach(function (value) {
  console.log(value);
  if (value === 5) {
    return false;
  }
})
输出结果照样是 357
同理 return false也不能执行
**for in 也同样存在这个问题**:

当然肯定有跳出forEach循环的办法,这里我举个栗子~ 使用try catch的方法

//   let arr = [{a:'1',b:'2',c:'3'},{a:'11',b:'22',c:'33'}];
// try {
//     arr.forEach((val) => {
//         if (val['b'] == '22') {
//             throw new Error('end-loop')
//         }
//         console.log('forEach-throw', val);
//         // {a:'1',b:'2',c:'3'};因为==22时,跳出整个循环了
//     })
// } catch (e) {
//     // console.log(e)
// }
这样就能跳出循环

总结

for in 适用于纯对象的遍历,并且只能输出可枚举属性

forEach适用于需要知道索引值的数组遍历,但是不能中断

for of适用于无需知道索引值的数组遍历,因为可以中断。另外对于其他字符串,类数组,类型数组的迭代,for of也更适用