JS绝大部分数据都可以遍历,但是遍历方式是不一样的,对可迭代对象(数组、字符串、Map、Set等)与非可迭代普通对象的遍历方式有区别。
下面从可迭代对象的遍历方式和不可迭代对象的遍历方式来整理JS中数据的遍历,做汇总。
一 可迭代对象的遍历方式
1. for
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
2. for...of:遍历可迭代对象,取到每一项
for (const item of arr) {
console.log(item);
}
3. forEach:纯遍历,无返回值
const arr = [1, 2, 3];
arr.forEach((item, index) => {
console.log(`索引 ${index}: ${item}`);
});
// 输出:
// 索引 0: 1
// 索引 1: 2
// 索引 2: 3
4. map:映射转换,返回新数组
const arr = [1, 2, 3];
// 将每个元素乘以 2
const newArr = arr.map(item => item * 2);
console.log(newArr); // [2, 4, 6]
console.log(arr); // [1, 2, 3] (原数组不变)
5. filter:筛选过滤,返回新数组
const arr = [1, 2, 3, 4, 5];
// 筛选出大于 2 的元素
const filtered = arr.filter(item => item > 2);
console.log(filtered); // [3, 4, 5]
6. find:查找第一个匹配项,并返回,如果没找到返回undefined
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Charlie' }
];
// 查找 id 为 2 的用户
const user = users.find(u => u.id === 2);
console.log(user); // { id: 2, name: 'Bob' }
7. findIndex:查找第一个匹配项的索引,并返回,如果没找到返回-1
const arr = [10, 20, 30, 40];
// 查找第一个大于 15 的元素的索引
const index = arr.findIndex(item => item > 15);
console.log(index); // 1 (因为 20 在索引 1 的位置)
8. some:是否存在至少一个满足条件,返回布尔值,只要找到一个满足条件的,立即停止遍历并返回true
const arr = [1, 2, 3, 4, 5];
// 是否有元素大于 4?
const hasLarge = arr.some(item => item > 4);
console.log(hasLarge); // true (因为 5 > 4)
// 是否有元素大于 10?
const hasHuge = arr.some(item => item > 10);
console.log(hasHuge); // false
9. every:是否所有元素都满足条件,只要找到一个不满足条件的,立即停止遍历并返回false
const arr = [2, 4, 6, 8];
// 是否所有元素都是偶数?
const allEven = arr.every(item => item % 2 === 0);
console.log(allEven); // true
// 是否所有元素都大于 3?
const allGt3 = arr.every(item => item > 3);
console.log(allGt3); // false (因为 2 不大于 3)
10. reduce:将数组所有元素“累加”成一个值,返回单个值,常用于求和、统计、扁平化等
const arr = [1, 2, 3, 4];
// 求和: acc 是累加器, cur 是当前值
const sum = arr.reduce((acc, cur) => acc + cur, 0);
console.log(sum); // 10
// 进阶:统计每个数字出现的次数
const counts = [1, 2, 2, 3].reduce((acc, cur) => {
acc[cur] = (acc[cur] || 0) + 1;
return acc;
}, {});
console.log(counts); // { '1': 1, '2': 2, '3': 1 }
二 普通对象的遍历方式
1. for...in:遍历普通对象,取到每一项的key
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
console.log(key, obj[key]);
}
}
2. Object.keys():返回对象的key组成的数组
Object.keys(obj).forEach(key => {
console.log(key, obj[key]);
});
3. Object.values():返回对象的值组成的数组
Object.values(obj).forEach(value => {
console.log(value);
});
4. Object.entries():返回对象的键值对组成的数组
for (const [key, value] of Object.entries(obj)) {
console.log(key, value);
}
总结
for...of是遍历可迭代对象的,for...in是遍历普通对象的。
数组有很多专属有特色功能的遍历函数:forEach、map、filter、find、findIndex、reduce、some、every,它们都不会改变原数组。
对象有四种主流遍历方式:for...in、Object.keys()、Object.values()、Object.entries()。
可迭代对象和普通对象的本质区别在于,普通对象的键值对是显性的,可迭代对象键值对的隐形的,它们的键是有序数字,值是每一项。