JavaScript 提供了多种遍历数组的方法,每种方法都有其特定的用途和特点。以下是主要的数组遍历方法:
1. 传统循环 (Traditional Loops)
这些是最基础、性能通常最好的方法。
for
循环:- 最灵活,可以正向、反向遍历,可以
break
或continue
。 - 需要手动管理索引。
- 最灵活,可以正向、反向遍历,可以
const arr = [1, 2, 3];
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
for...in
循环:- 不推荐用于数组。它设计用于遍历对象的可枚举属性,可能会遍历到数组的非数字索引属性或继承的属性,且顺序不能保证。
- 对于纯数组,它也能工作,但有潜在风险。
// 不推荐
for (let index in arr) {
console.log(arr[index]);
}
for...of
循环:- ES6 引入,专门用于遍历可迭代对象(如数组、字符串、Map、Set)。
- 直接获取元素值,不能直接获取索引(但可以用
entries()
)。 - 支持
break
,continue
,return
。
for (let value of arr) {
console.log(value);
}
// 获取索引和值
for (let [index, value] of arr.entries()) {
console.log(index, value);
}
2. 数组方法 (Array Methods)
这些是数组原型上的高阶函数,接受回调函数作为参数。
forEach(callback)
:- 为数组中的每个元素执行一次回调函数。
- 返回
undefined
,不能链式调用或中断(return
只能跳出当前回调,不能跳出整个遍历)。 - 适用于执行副作用(如修改 DOM、累加变量)。
arr.forEach((value, index, array) => {
console.log(value);
});
map(callback)
:- 创建一个新数组,其结果是原数组每个元素调用回调函数后的返回值。
- 返回一个新数组。
- 适用于数据转换。
const newArr = arr.map(value => value * 2);
filter(callback)
:- 创建一个新数组,包含所有回调函数返回
true
的元素。 - 返回一个新数组。
- 适用于筛选数据。
- 创建一个新数组,包含所有回调函数返回
const even = arr.filter(value => value % 2 === 0);
reduce(callback, initialValue)
:- 将数组“归约”为一个单一的值(可以是数字、字符串、对象、数组等)。
- 返回归约后的结果。
- 功能强大,可以模拟
map
、filter
等。
const sum = arr.reduce((acc, value) => acc + value, 0);
some(callback)
:- 测试数组中是否有至少一个元素通过了回调函数的测试。
- 返回
true
或false
。 - 一旦找到满足条件的元素就立即返回
true
(短路)。
const hasEven = arr.some(value => value % 2 === 0);
every(callback)
:- 测试数组中的所有元素是否都通过了回调函数的测试。
- 返回
true
或false
。 - 一旦找到不满足条件的元素就立即返回
false
(短路)。
const allPositive = arr.every(value => value > 0);
find(callback)
:- 返回数组中满足回调函数条件的第一个元素的值。
- 如果没有找到,返回
undefined
。 - 找到后立即停止遍历(短路)。
const firstEven = arr.find(value => value % 2 === 0);
findIndex(callback)
:- 返回数组中满足回调函数条件的第一个元素的索引。
- 如果没有找到,返回
-1
。 - 找到后立即停止遍历(短路)。
const index = arr.findIndex(value => value > 2);
keys()
,values()
,entries()
:- 返回一个迭代器对象,可用于
for...of
循环。 keys()
: 遍历索引。values()
: 遍历元素值(等同于for...of
)。entries()
: 遍历[index, value]
键值对。
- 返回一个迭代器对象,可用于
for (let key of arr.keys()) { ... }
for (let value of arr.values()) { ... }
for (let [index, value] of arr.entries()) { ... }
3. 其他方法
for await...of
: 用于遍历异步可迭代对象(如异步生成器)。
如何选择?
- 需要获取索引或需要
break
/continue
? → 使用for
循环 或for...of
+entries()
。 - 需要创建一个新数组? → 使用
map
。 - 需要筛选元素? → 使用
filter
。 - 需要将数组合并成一个值? → 使用
reduce
。 - 只是想对每个元素执行操作(如打印、修改外部变量)? → 使用
forEach
。 - 检查是否存在满足条件的元素? → 使用
some
。 - 检查是否所有元素都满足条件? → 使用
every
。 - 查找一个元素或它的索引? → 使用
find
或findIndex
。
理解每种方法的返回值和目的是选择正确方法的关键。
THE END