for、for-in、for-of、forEach 的区别

223 阅读3分钟

for 、for-in、for-of、forEach 的区别,主要在于能否中断循环和遍历性能

语法

  1. for 循环

语法:

for (初始化; 条件; 迭代) { ... }

特点:

  • 最基础的循环,通过索引遍历数组或类数组对象。
  • 完全控制循环过程(步长、条件、中断)。
  • 性能最优,无额外函数调用开销。
  • 适用场景:需要精确控制循环逻辑(如倒序、步长调整)或高性能场景。 示例:
const arr = [1, 2, 3]
for (let i = 0; i < arr.length; i++) {
  console.log(arr[i])
}
  1. for-in 循环

语法:

for (const key in object) { ... }

特点:

  • 遍历对象的可枚举属性(包括原型链上的属性)。
  • 不保证顺序,通常用于遍历对象键值对。
  • 不适用于数组(可能遍历到非自有属性或方法)。
  • 需配合 hasOwnProperty 过滤自有属性。

示例:

const obj = { a: 1, b: 2 }
for (const key in obj) {
  if (obj.hasOwnProperty(key)) {
    console.log(key, obj[key])
  }
}
  1. for-of 循环(ES6+)

语法:

for (const value of iterable) { ... }

特点:

  • 遍历可迭代对象(如数组、字符串、Map、Set)。
  • 按插入顺序遍历,直接获取元素值(非索引)。
  • 可中断(支持 break 和 continue)。
  • 适用场景:遍历数组、字符串或可迭代对象,需保持顺序或值操作。

示例:

const arr = ['a', 'b', 'c']
for (const value of arr) {
  console.log(value)
}
  1. forEach 方法

语法:

array.forEach((value, index, array) => { ... });

特点:

  • 数组专属方法,遍历数组元素。
  • 不可中断(无法用 break 或 return 终止)。
  • 函数式风格,简洁但性能略低于 for 循环。
  • 适用场景:简单遍历数组,无需复杂逻辑。

示例:

const arr = [1, 2, 3]
arr.forEach((value, index) => {
  console.log(value)
})

优缺点

  • for

    • 优点:程序简洁,结构清晰,循环初始化,循环变量化和循环条件位置突出
    • 缺点:结构比 while 循环复杂,容易出编码错误
    • 适用场景:遍历数组,对象,字符串
    • break、continue:支持
  • for-in

    • 优点:可以使用 break、continue,不仅支持数组的遍历,还可以遍历类似数组的对象,支持字符串的遍历最简洁
    • 缺点:适用于处理原有的原生对象
    • 适用场景:遍历对象,遍历字符串
    • break、continue:支持
  • for-of

    • 优点:避免了 for-in 的所有缺点,支持 break、continue、return。支持遍历 map,object,array,set string 等
    • 缺点:不适用于处理原有的原生对象
    • 适用场景:遍历数组,遍历 map,object,set
    • break、continue:支持
  • forEach

    • 优点:便利的时候更加简洁,不用关心集合下标的问题,减少了出错的效率
    • 缺点:不能同时遍历多个集合,在遍历的时候无法修改和删除集合数据,方法不能使用 break,continue 语句跳出循环,或者使用 return 从函数体返回,对于空数组不会执行回调函数
    • 适用场景:遍历数组,遍历 map,object,set
    • break、continue:不支持

关键区别总结

特性forfor-infor-offorEach
目标类型数组/类数组对象属性可迭代对象数组
顺序保证
中断支持✅ (break)✅ (break)✅ (break)
性能最高中等中等
代码简洁性最高
适用场景复杂逻辑控制对象遍历可迭代对象遍历简单数组遍历

使用建议

  • 优先 for-of:遍历数组、字符串或可迭代对象。
  • 优先 forEach:简单遍历数组且无需中断。
  • 避免 for-in 遍历数组:可能遍历到非自有属性。
  • 需要性能时选 for 循环:如处理大规模数据。