浅谈for...in, for...of, forEach的区别

379 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情

总结(写在前头)

  • for...in和for...of属于es6中新增的数组实例方法。forEach是es5中规定的数组实例方法。
  • for...in、for...of和forEach都可以用来遍历数组。其中for...in还可以用来遍历对象。而for...of和forEach只能用来遍历数组。但是由于for...in是遍历对象的可枚举属性,所以不建议使用for...in遍历数组。
  • 遍历数值时,for...of可以使用return和break跳出循环,而forEach只能通过try-catch捕获异常来跳出循环。

for...in

  • for...in属于es6中的数组实例方法,属于Object原型上得方法。用来遍历对象的属性,准确的说是遍历对象身上可枚举的属性。关于对象的可枚举性,可以参考这篇文章:深入理解Javascript之对象
  • 使用方式
let obj = { a: 1, b: 2 };
for (let key in obj) {
    console.log(key);
}
// a
// b
  • 注意:如果对象某个属性的enumerable特性为false,则是无法通过for...in循环遍历出来
let obj = { a:1, b: 2 };
Object.defineProperty(obj, 'b', {
    enumerable: false
});
for (let key in obj) {
    console.log(key);
}
// a
  • 同时对于数组而言,同样可以使用for...in来进行遍历,返回的是数组的下标。
  • 使用方式:
let arr = [1,2,3,4];
for (let key in arr) {
    console.log(key)
}
// 0
// 1
// 2
// 3
  • 注意:不建议通过for...in来进行数组的遍历。因为for...in会遍历出原型对象以及对象本身属性值。所以该方法因为遍历属性而增加相应的时间开销。无形上增加了性能开销。

forEach

  • forEach属于es5中数组的实例方法。
  • forEach无法遍历对象,如果非要遍历对象,除了使用for...in方法之外,还可以通过对象实例上得方法:Object.keys()和Object.values()方法,来将对象的键或者值转化成数组,然后再进行遍历。
  • 用法:
// 遍历数组
let arr = [1,2,3,4];
arr.forEach((item, index) => {
    console.log(item, index);
})
// 1 0 
// 2 1 
// 3 2 
// 4 3

// 遍历对象
let obj = { a: 1, b: 2 };
Object.keys(arr).forEach((item, index) => {
    console.log(item, index)
})
// a 0 
// b 1 
// 或者:
let obj = { a: 1, b: 2 };
Object.values(arr).forEach((item, index) => {
    console.log(item, index)
})
// 1 0 
// 2 1 
  • 注意事项:使用forEach时无法通过return、break停止循环。如果有停止循环的需求,除了使用原生的for循环,do-while,或者while之外,只能通过try-catch来进行处理。
  • 比如:
let arr = [ 1, 2, 3, 4 ];
try {
    arr.forEach((item, index) => {
        if (item == 2) throw new Error('stop')
        console.log(item);
    })
} catch(error) {
    if (error.message == 'stop') return
}
// 1
  • 额外知识点:如果数组的元素中有对象的话,可以通过item.[属性名] 来改变原数组。

for...of

  • for...of属于es6的数组实例方法,与es5中的forEach不同的是for...of可以使用return和break来跳出循环。解决了forEach的缺点。
  • 使用方法:
let arr = [1, 2, 3, 4];
for (let value of arr) {
    console.log(value);
    if (value == 3) return;
}
// 1
// 2 
// 3