JavaScript 面试题
目录

请解释 forEach、map、for...in 和 for...of 循环的区别和适用场景。

· 约 5 分钟读完 · 第 53 / 507 章

推荐答案

forEach、map、for...in 和 for...of 循环在 JavaScript 中都用于迭代,但它们之间存在关键差异,适用于不同的场景:

  • forEach:

    • 用途: 主要用于遍历数组的元素,并对每个元素执行指定的回调函数。
    • 特点: 不会返回新的数组,总是返回 undefined,不能使用 break 或 continue 跳出循环,主要用于执行副作用操作(例如,修改 DOM 或打印日志)。
    • 适用场景: 需要遍历数组并对每个元素执行操作,且不需要返回新数组的情况。
  • map:

    • 用途: 遍历数组的元素,并对每个元素执行指定的回调函数,最终返回一个由回调函数的返回值组成的新数组。
    • 特点: 会返回一个新的数组,不会修改原数组,可用于链式调用。
    • 适用场景: 需要基于现有数组创建新数组,并对原数组的每个元素进行转换的情况。
  • for...in:

    • 用途: 遍历对象的可枚举属性(包括原型链上的属性)。
    • 特点: 遍历的是键名(属性名),而不是值,遍历顺序不保证,主要用于遍历对象,不推荐用于遍历数组,可能遍历到自定义属性。
    • 适用场景: 需要遍历对象的属性,特别是当对象是稀疏数组或键值不为数字的数组时。
  • for...of:

    • 用途: 遍历可迭代对象的值,例如数组、字符串、Map、Set、arguments 等。
    • 特点: 遍历的是值,而不是索引或键名,可以使用 break 和 continue 跳出循环。
    • 适用场景: 需要遍历数组或其他可迭代对象的值,且不需要索引时,相比 forEach 可使用 break 等。

本题详细解读

1. forEach

forEach 是数组的内置方法,它接受一个回调函数作为参数,该回调函数会对数组中的每个元素执行一次。

  • 参数: 回调函数接收三个参数:当前元素值、当前元素的索引、数组本身。
  • 返回值: forEach 总是返回 undefined。
  • 中断: 无法使用 break 或 continue 来提前终止循环。

2. map

map 也是数组的内置方法,它会对数组中的每个元素执行回调函数,并返回一个由回调函数的返回值组成的新数组。

  • 参数: 与 forEach 类似,回调函数接收三个参数:当前元素值、当前元素的索引、数组本身。
  • 返回值: 返回一个新数组,新数组的元素为回调函数的返回值。
  • 用途: 常用于对数组中的元素进行转换。

3. for...in

for...in 循环主要用于遍历对象的属性,它会遍历对象及其原型链上的所有可枚举属性。

  • 遍历内容: 遍历的是对象的键名(属性名)。
  • 顺序: 遍历顺序是不确定的,可能因浏览器而异。
  • 数组: 虽然可以用于遍历数组,但不推荐,因为它会遍历数组的自定义属性,且顺序不稳定。
  • 原型链: 会遍历原型链上的可枚举属性。

4. for...of

for...of 循环可以遍历可迭代对象的值,包括数组、字符串、Map、Set 等。

  • 遍历内容: 遍历的是可迭代对象的值。
  • 顺序: 遍历顺序与对象中元素的顺序一致。
  • 中断: 可以使用 break 和 continue 来提前终止循环。
  • 兼容性: for...of 需要ES6的支持,老版本浏览器可能不支持

适用场景总结:

  • forEach: 执行副作用操作,不需要返回新数组。
  • map: 基于现有数组创建新数组,并对元素进行转换。
  • for...in: 遍历对象的属性,包括原型链上的属性。
  • for...of: 遍历可迭代对象的值,需要使用break或continue中断。