数组遍历方法
数组是JavaScript中最常用的数据结构之一,处理数组时经常需要遍历元素。JavaScript提供了多种遍历方法,每种方法都有其特点和适用场景。
for循环
最基本的遍历方式是传统的for
循环,通过索引访问数组元素:
const fruits = ['apple', 'banana', 'orange'];
for (let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}
这种方式可以精确控制循环过程,包括中断循环或跳过某些元素:
for (let i = 0; i < fruits.length; i++) {
if (i === 1) continue; // 跳过第二个元素
if (fruits[i] === 'orange') break; // 遇到orange时终止循环
console.log(fruits[i]);
}
for...of循环
ES6引入的for...of
语法提供更简洁的遍历方式:
for (const fruit of fruits) {
console.log(fruit);
}
这种语法直接获取元素值而非索引,但不能直接获取当前元素的索引位置。要获取索引可以结合数组的entries()
方法:
for (const [index, fruit] of fruits.entries()) {
console.log(index, fruit);
}
forEach方法
数组的forEach
方法接受一个回调函数作为参数:
fruits.forEach(function(fruit, index) {
console.log(index, fruit);
});
使用箭头函数可以更简洁:
fruits.forEach((fruit, index) => {
console.log(index, fruit);
});
forEach
无法使用break
或return
中断循环,要提前终止需要抛出异常:
try {
fruits.forEach(fruit => {
if (fruit === 'banana') throw new Error('Stop iteration');
console.log(fruit);
});
} catch (e) {
if (e.message !== 'Stop iteration') throw e;
}
map方法
map
方法遍历数组并返回一个新数组:
const upperFruits = fruits.map(fruit => fruit.toUpperCase());
console.log(upperFruits); // ['APPLE', 'BANANA', 'ORANGE']
回调函数接收三个参数:当前元素、索引和数组本身:
const fruitWithIndex = fruits.map((fruit, index) => `${index}:${fruit}`);
console.log(fruitWithIndex); // ['0:apple', '1:banana', '2:orange']
filter方法
filter
方法返回满足条件的元素组成的新数组:
const longFruits = fruits.filter(fruit => fruit.length > 5);
console.log(longFruits); // ['banana', 'orange']
reduce方法
reduce
方法将数组元素累积为单个值:
const numbers = [1, 2, 3, 4];
const sum = numbers.reduce((accumulator, current) => accumulator + current, 0);
console.log(sum); // 10
初始值可以省略,此时使用数组第一个元素作为初始值:
const product = numbers.reduce((acc, curr) => acc * curr);
console.log(product); // 24
some和every方法
some
测试是否有元素满足条件:
const hasApple = fruits.some(fruit => fruit === 'apple');
console.log(hasApple); // true
every
测试是否所有元素都满足条件:
const allLong = fruits.every(fruit => fruit.length > 3);
console.log(allLong); // true
find和findIndex方法
find
返回第一个满足条件的元素:
const firstLong = fruits.find(fruit => fruit.length > 5);
console.log(firstLong); // 'banana'
findIndex
返回第一个满足条件的元素的索引:
const firstLongIndex = fruits.findIndex(fruit => fruit.length > 5);
console.log(firstLongIndex); // 1
keys、values和entries方法
这些方法返回迭代器对象:
for (const index of fruits.keys()) {
console.log(index); // 0, 1, 2
}
for (const value of fruits.values()) {
console.log(value); // 'apple', 'banana', 'orange'
}
for (const [index, value] of fruits.entries()) {
console.log(index, value); // 0 'apple', 1 'banana', 2 'orange'
}
性能考虑
不同遍历方法性能有差异。对于大型数组,传统for
循环通常最快:
console.time('for loop');
for (let i = 0; i < 1000000; i++) {}
console.timeEnd('for loop');
console.time('forEach');
Array(1000000).forEach(() => {});
console.timeEnd('forEach');
稀疏数组处理
稀疏数组(含有empty项)的处理方式不同:
const sparse = [1,,3];
sparse.forEach(x => console.log(x)); // 1, 3
for (const x of sparse) console.log(x); // 1, undefined, 3
修改原数组
遍历时修改原数组可能导致意外行为:
const numbers = [1, 2, 3];
numbers.forEach((num, index) => {
numbers.push(num * 2); // 会导致无限循环
});
类数组对象
处理类数组对象(如arguments、NodeList)时:
function logArgs() {
Array.prototype.forEach.call(arguments, arg => {
console.log(arg);
});
}
logArgs(1, 2, 3);
现代JavaScript中更推荐使用Array.from:
const nodeList = document.querySelectorAll('div');
Array.from(nodeList).forEach(div => {
console.log(div);
});
异步遍历
处理异步操作时,forEach
不会等待Promise:
const urls = ['url1', 'url2'];
urls.forEach(async url => {
await fetch(url); // 不会按顺序执行
});
可以使用for...of
配合await
:
for (const url of urls) {
await fetch(url); // 按顺序执行
}
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:数组基本操作(增删改查)
下一篇:数组排序与搜索