Array traversal methods
Arrays are one of the most commonly used data structures in JavaScript, and traversing elements is often required when working with them. JavaScript provides multiple traversal methods, each with its own characteristics and suitable scenarios.
for Loop
The most basic traversal method is the traditional for
loop, which accesses array elements via indices:
const fruits = ['apple', 'banana', 'orange'];
for (let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}
This method allows precise control over the loop, including interrupting the loop or skipping certain elements:
for (let i = 0; i < fruits.length; i++) {
if (i === 1) continue; // Skip the second element
if (fruits[i] === 'orange') break; // Terminate the loop when encountering 'orange'
console.log(fruits[i]);
}
for...of Loop
The for...of
syntax introduced in ES6 provides a more concise way to traverse arrays:
for (const fruit of fruits) {
console.log(fruit);
}
This syntax directly retrieves the element values rather than indices, but it cannot directly access the current element's index. To obtain the index, you can combine it with the array's entries()
method:
for (const [index, fruit] of fruits.entries()) {
console.log(index, fruit);
}
forEach Method
The forEach
method of arrays accepts a callback function as a parameter:
fruits.forEach(function(fruit, index) {
console.log(index, fruit);
});
Using arrow functions makes it even more concise:
fruits.forEach((fruit, index) => {
console.log(index, fruit);
});
forEach
cannot be interrupted using break
or return
. To terminate early, you need to throw an exception:
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 Method
The map
method traverses the array and returns a new array:
const upperFruits = fruits.map(fruit => fruit.toUpperCase());
console.log(upperFruits); // ['APPLE', 'BANANA', 'ORANGE']
The callback function receives three parameters: the current element, its index, and the array itself:
const fruitWithIndex = fruits.map((fruit, index) => `${index}:${fruit}`);
console.log(fruitWithIndex); // ['0:apple', '1:banana', '2:orange']
filter Method
The filter
method returns a new array composed of elements that meet the specified condition:
const longFruits = fruits.filter(fruit => fruit.length > 5);
console.log(longFruits); // ['banana', 'orange']
reduce Method
The reduce
method accumulates array elements into a single value:
const numbers = [1, 2, 3, 4];
const sum = numbers.reduce((accumulator, current) => accumulator + current, 0);
console.log(sum); // 10
The initial value can be omitted, in which case the first element of the array is used as the initial value:
const product = numbers.reduce((acc, curr) => acc * curr);
console.log(product); // 24
some and every Methods
some
tests whether at least one element meets the condition:
const hasApple = fruits.some(fruit => fruit === 'apple');
console.log(hasApple); // true
every
tests whether all elements meet the condition:
const allLong = fruits.every(fruit => fruit.length > 3);
console.log(allLong); // true
find and findIndex Methods
find
returns the first element that meets the condition:
const firstLong = fruits.find(fruit => fruit.length > 5);
console.log(firstLong); // 'banana'
findIndex
returns the index of the first element that meets the condition:
const firstLongIndex = fruits.findIndex(fruit => fruit.length > 5);
console.log(firstLongIndex); // 1
keys, values, and entries Methods
These methods return iterator objects:
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'
}
Performance Considerations
Different traversal methods vary in performance. For large arrays, the traditional for
loop is usually the fastest:
console.time('for loop');
for (let i = 0; i < 1000000; i++) {}
console.timeEnd('for loop');
console.time('forEach');
Array(1000000).forEach(() => {});
console.timeEnd('forEach');
Handling Sparse Arrays
Sparse arrays (those with empty slots) are handled differently:
const sparse = [1,,3];
sparse.forEach(x => console.log(x)); // 1, 3
for (const x of sparse) console.log(x); // 1, undefined, 3
Modifying the Original Array
Modifying the original array during traversal can lead to unexpected behavior:
const numbers = [1, 2, 3];
numbers.forEach((num, index) => {
numbers.push(num * 2); // Will cause an infinite loop
});
Array-like Objects
When dealing with array-like objects (e.g., arguments
, NodeList
):
function logArgs() {
Array.prototype.forEach.call(arguments, arg => {
console.log(arg);
});
}
logArgs(1, 2, 3);
Modern JavaScript recommends using Array.from
:
const nodeList = document.querySelectorAll('div');
Array.from(nodeList).forEach(div => {
console.log(div);
});
Asynchronous Traversal
When handling asynchronous operations, forEach
does not wait for Promises:
const urls = ['url1', 'url2'];
urls.forEach(async url => {
await fetch(url); // Will not execute in order
});
You can use for...of
with await
instead:
for (const url of urls) {
await fetch(url); // Executes in order
}
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:数组基本操作(增删改查)
下一篇:数组排序与搜索