js数组遍历需按目的选方法:改原数组用for,转换用map,筛选用filter,判断用some/every,聚合用reduce,查找用find/findindex;for循环适用于break/continue、反向遍历及修改原数组等场景。

JS 中数组遍历不是“选一个用就行”,而是根据目的来定方法。核心就三点:要不要改原数组、要不要返回新数据、要不要提前中断、需不需要索引或原数组上下文。
按目的选方法:一眼锁定该用谁
不同方法语义清晰,名字就是用途:
-
只执行操作(如打日志、发请求、修改外部变量)→ 用
forEach:无返回值,不生成新数组,语义明确是“遍历并做点事” -
要转换每个元素 → 用
map:必须有 return,返回等长新数组,原数组不变 -
要筛选符合条件的元素 → 用
filter:回调返回 true 的项组成新数组,长度可能变短 -
要判断是否存在/是否全部满足 → 用
some或every:返回布尔值,找到即停(some找到第一个 true 就终止;every遇到第一个 false 就终止) -
要聚合计算(求和、拼接、找最大值等)→ 用
reduce:接收累加器和当前值,适合归约类逻辑 -
要找某个匹配项本身或它的索引 → 用
find或findIndex:找到第一个就返回,不继续遍历
for 循环和 for...of 不是过时货,而是有不可替代场景
高阶函数虽简洁,但有些事它们干不了:
-
需要中途 break 或 continue → 优先用
for或for...of:比如遍历商品列表,找到第一个库存为 0 的就跳出,some或find可以做到,但若逻辑更复杂(如跳过某些项再继续),for更直接可控 -
需要反向遍历、步长非 1、或复用索引做其他计算 →
for最灵活:例如从后往前删除满足条件的元素,避免索引偏移问题 -
遍历同时修改原数组 →
for是最安全的选择:因为forEach、map等都不改变原数组,强行在回调里改arr[i]虽然能生效,但语义混乱,易出错
别忽略参数细节和常见坑
所有数组方法回调默认接收三个参数:value、index、array,但实际使用中容易踩坑:
-
箭头函数没有自己的
this,传thisArg失效:如果回调里要用this指向某个对象,得用普通函数,并传第二个参数;否则直接用外部变量或显式绑定 -
for...in不适合数组:它遍历的是对象的可枚举属性名,对数组会返回字符串索引("0", "1"),还可能遍历到原型上添加的属性,极不稳定 -
forEach无法被 break/return 中断:想跳出只能抛异常(不推荐)或改用for循环 -
空数组时,
forEach、map、filter等均不执行回调:这是设计行为,不是 bug,但写逻辑时要意识到这点
性能与可读性之间,通常优先选可读性
现代 JS 引擎对 map、filter 等优化得很好,小到中等规模数组(几万项内),性能差异几乎感知不到。而可读性带来的长期收益更大:
-
arr.filter(x => x > 10).map(x => x * 2)比嵌套for更容易看出“先筛再转”的意图 - 团队协作中,
some比手写循环加标志位更直观表达“是否存在” - 过度追求极致性能(如缓存
arr.length)在多数业务场景中意义不大,除非明确压测发现是瓶颈











