JavaScript数组遍历的几种方式

对于JavaScript的数组,除了最基本的for循环(包括最基本的下标遍历和for of),我们还可以用其他方法根据不同场景的需求对数组进行遍历。

forEach

ES5的特性,即使没有jQuery也可以直接用forEach遍历数组,用法如下:

1
2
3
4
var arr = [1, 2, 3];
arr.forEach(function(value, index) {
console.log(`${value}, ${index}`);
});

forEach有两个特点需要特别注意,第一是其性能要比经典下标遍历差,差距比较大,不适合用于遍历数据很大的数组。第二是forEach循环不能中途跳出,不像经典的下标遍历能够打断。

map

这个办法本身是基于原数组根据某个方法生成新数组,如下:

1
2
3
var arr = [1, 2, 3];
var new_arr = arr.map(x => x * 2);
console.log(new_arr);

这个时候得到的new_arr是[2, 4, 6]。

由于这个方法也会扫描数组里面的每一个元素,所以我们可以用它来做遍历,MDN给出的语法如下:

1
2
3
var new_array = arr.map(function callback(currentValue[, index[, array]]) {
// Return element for new_array
}[, thisArg])

利用callback内的currentValue,我们可以实现类似于map的遍历:

1
2
3
4
var arr = [1, 2, 3];
arr.map(value => {
console.log(value);
});

由于map本身是创建一个新数组的方法,它存在一个返回值的问题,性能要比forEach还要低一些。

我们可以直接把map单独拿出来调用,例如MDN上的这个例子:

1
2
3
4
5
var map = Array.prototype.map
var a = map.call("Hello World", function(x) {
return x.charCodeAt(0);
})
// a的值为[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]

它是直接把map这个方法赋给了一个变量,然后用call调用。类似地这个方法也可以用来遍历筛选出的DOM元素等。

filter

filter这个函数也可以被用来遍历数组,例子如下:

1
2
3
4
var arr = [1, 2, 3];
arr.filter(function (number) {
console.log(number);
});

这个方法也会扫描整个数组,每个元素都会进入一次callback。

其特性是它并不会改变原数组,同时原数组中未被赋值的、被删除掉的元素会被filter方法自动跳过。

使用filter方法我们也可以有条件地创建一个新的数组:

1
2
3
4
5
6
var arr = [1, 2, 3, 4, 5, 6, 7];
var new_arr = arr.filter(value => {
return value > 3;
});
console.log(new_arr);
// [4, 5, 6, 7]

every

every是可中断的遍历,在callback的返回至为false的时候就会中断,不像forEach一样是不可中断的。和filter一样,未被赋值或已删除的元素不会进入callback。

例子:

1
2
3
4
5
var arr = [1,2,3,4,5];
var result = arr.every(function (item, index) {
return item > 0;
});
console.log(result);

every是有返回值的,这个返回值是一个布尔量,一旦回调反回了false,every回直接返回false,如果没有返回,而是所有变量的结果都是true,那么every的返回值也是true,且数组被完整遍历了一遍。

some

some和every是一样的用法,只是逻辑上是相反的,它是在callback返回值为true的时候中断。

1
2
3
4
5
var arr = [1,2,3,4,5];
var result = arr.every(function (item, index) {
return item > 0;
});
console.log(result);

需要注意的是some的返回值也和回调的返回值是同步的,回调返回true,遍历中止,some函数返回true,这一点它和every也相反。