在 JavaScript 中,数组是一种非常重要的数据类型,它可以存储一系列的数据,而且数组中的元素可以是不同的数据类型。在实际开发中,我们经常需要对数组进行遍历,这是一个非常基本的操作。本文将从多个角度分析 JS 数组的遍历,包括常见的遍历方法、性能比较、ES6 新特性以及一些实际应用场景。
常见的数组遍历方法
1. for 循环
for 循环是最常见的遍历数组的方法,它可以很方便地遍历数组中的每一个元素。
```
var arr = [1, 2, 3, 4, 5];
for (var i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
```
2. forEach
forEach 是 ES5 新增的数组遍历方法,它可以更加简洁地遍历数组中的每一个元素。
```
var arr = [1, 2, 3, 4, 5];
arr.forEach(function(item) {
console.log(item);
});
```
3. map
map 是 ES5 新增的数组遍历方法,它可以遍历数组中的每一个元素,并返回一个新的数组。
```
var arr = [1, 2, 3, 4, 5];
var newArr = arr.map(function(item) {
return item * 2;
});
console.log(newArr); // [2, 4, 6, 8, 10]
```
4. filter
filter 是 ES5 新增的数组遍历方法,它可以遍历数组中的每一个元素,并根据条件过滤出符合条件的元素。
```
var arr = [1, 2, 3, 4, 5];
var newArr = arr.filter(function(item) {
return item > 3;
});
console.log(newArr); // [4, 5]
```
5. reduce
reduce 是 ES5 新增的数组遍历方法,它可以遍历数组中的每一个元素,并将它们累加起来。
```
var arr = [1, 2, 3, 4, 5];
var sum = arr.reduce(function(total, item) {
return total + item;
}, 0);
console.log(sum); // 15
```
性能比较
在实际开发中,我们需要考虑数组遍历的性能。下面是一组性能测试数据:
```
var arr = [];
for (var i = 0; i < 1000000; i++) {
arr.push(i);
}
console.time('for');
for (var i = 0; i < arr.length; i++) {
var item = arr[i];
}
console.timeEnd('for');
console.time('forEach');
arr.forEach(function(item) {
var item = item;
});
console.timeEnd('forEach');
console.time('map');
var newArr = arr.map(function(item) {
return item * 2;
});
console.timeEnd('map');
console.time('filter');
var newArr = arr.filter(function(item) {
return item > 500000;
});
console.timeEnd('filter');
console.time('reduce');
var sum = arr.reduce(function(total, item) {
return total + item;
}, 0);
console.timeEnd('reduce');
```
测试结果如下:
```
for: 3.995849609375ms
forEach: 7.18798828125ms
map: 11.736083984375ms
filter: 47.838134765625ms
reduce: 6.909423828125ms
```
可以看到,for 循环的性能最好,其次是 reduce,最慢的是 filter。在实际开发中,我们需要根据具体情况选择合适的遍历方法。
ES6 新特性
在 ES6 中,新增了一些数组遍历的新特性,包括 for...of 和 entries。
1. for...of
for...of 可以遍历数组中的每一个元素。
```
var arr = [1, 2, 3, 4, 5];
for (var item of arr) {
console.log(item);
}
```
2. entries
entries 可以遍历数组中的每一个元素,并返回一个由索引和值组成的数组。
```
var arr = [1, 2, 3, 4, 5];
for (var [index, item] of arr.entries()) {
console.log(index, item);
}
```
实际应用场景
数组遍历是一个非常基本的操作,它在实际开发中应用非常广泛。下面是一些实际应用场景:
1. 数组去重
数组去重是一个常见的应用场景,我们可以使用 filter 或者 ES6 的 Set 来实现。
```
// 使用 filter
var arr = [1, 2, 3, 3, 4, 5, 5];
var newArr = arr.filter(function(item, index, arr) {
return arr.indexOf(item) === index;
});
console.log(newArr); // [1, 2, 3, 4, 5]
// 使用 Set
var arr = [1, 2, 3, 3, 4, 5, 5];
var set = new Set(arr);
var newArr = Array.from(set);
console.log(newArr); // [1, 2, 3, 4, 5]
```
2. 数组排序
数组排序是一个常见的应用场景,我们可以使用 sort 方法来实现。
```
var arr = [3, 2, 1, 5, 4];
arr.sort(function(a, b) {
return a - b;
});
console.log(arr); // [1, 2, 3, 4, 5]
```
3. 数组扁平化
数组扁平化是一个常见的应用场景,我们可以使用递归或者 ES6 的 flat 方法来实现。
```
// 递归
var arr = [1, [2, [3, 4]]];
function flatten(arr) {
var res = [];
for (var i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
res = res.concat(flatten(arr[i]));
} else {
res.push(arr[i]);
}
}
return res;
}
console.log(flatten(arr)); // [1, 2, 3, 4]
// ES6
var arr = [1, [2, [3, 4]]];
var newArr = arr.flat(Infinity);
console.log(newArr); // [1, 2, 3, 4]
```