JS 数据遍历

36 阅读3分钟

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()。

可迭代对象和普通对象的本质区别在于,普通对象的键值对是显性的,可迭代对象键值对的隐形的,它们的键是有序数字,值是每一项。