![](https://qny.aqingya.cn/img/37073a4791b24b428442d8a82fccc5d3 (1).jpg)

但在开始详细介绍之前,很有必要对ECMAScript 5中的数组方法做一个概述。首先,大多数方法的第一个参数接收一个函数,并且对数组的每个元素(或一些元素)调用一次该函数。如果是稀疏数组,对不存在的元素不调用传递的函数。在大多数情况下,调用提供的函数使用三个参数:数组元素、元素的索引和数组本身。通常,只需要第一个参数值,可以忽略后两个参数。大多数ECMAScript 5数组方法的第一个参数是一个函数,第二个参数是可选的。如果有第二个参数,则调用的函数被看做是第二个参数的方法。也就是说,在调用函数时传递进去的第二个参数作为它的this关键字的值来使用。被调用的函数的返回值非常重要,但是不同的方法处理返回值的方式也不一样。ECMAScript 5中的数组方法都不会修改它们调用的原始数组。当然,传递给这些方法的函数是可以修改这些数组的。

forEach()

forEach()方法从头到尾遍历数组,每一个元素调用指定的函数。如上所述,传递的函数作为forEach()的第一个参数,然后forEach()使用三个参数调用该函数:数组元素、元素的索引和数组本身。如果只关心数组元素的值,可以编写只有一个参数的函数—额外的参数将忽略。

1
2
3
4
5
6
var a = [1, 2, 3, 4];
var sum = 0;
a.forEach(function(x) {
return sum += x;
})
console.log(sum); // 10

注意:forEach()无法在所有元素都传递给调用的函数之前终止遍历。也就是说,没有像for循环中使用的响应的break()语句。如果要提前终止,必须把forEach()方法放在一个try块中,并能抛出一个异常。如果forEach()调用的函数抛出foreach.break异常,循环会提前终止。

map()

map()方法将调用的数组的每一个元素传递给指定的函数,并且返回一个数组,它包含该函数的返回值。例如:

1
2
3
4
5
var a = [1, 2, 3];
b = a.map(function(x) {
return x += 1;
});
console.log(b); // [2, 3, 4]

传递给map()的函数的调用方式和传递给forEach()的函数的调用方式一样,但出传递给map()的函数应该有返回值。注意,map()返回的是一个新数组:它不修改调用的数组。如果是稀疏数组,返回的也是相同方式的稀疏数组:它具有相同的长度,相同的缺失元素。

1
2
3
4
5
var a = [1, 2, 3, , undefined, 5];
b = a.map(function(x) {
return x += 1;
});
console.log(b); // [2, 3, 4, empty, NaN, 6]

filter()

filter()方法返回的数组元素是调用的数组的一个子集。传递的函数是用来逻辑判定的:该函数返回true或者false。调用判定函数就像调用forEach()和map()一样,如果返回值为true或者能转化为true的值,那么传递给判定函数的元素就是这个子集的成员,他将被添加到一个作为返回值的数组中。例如:

1
2
3
4
5
var a = [1, 2, 3, 4, 5, 6]
b = a.filter(function(x) {
return x > 3;
});
console.log(b) // [4, 5, 6]

注意:filter()会跳过稀疏数组中缺少的元素,它的返回数组总是稠密的。为了压缩稀疏数组的空缺,代码如下:

1
2
3
4
5
var a = [1, 2, 3, , , ]
var aa = a.filter(function() {
return true;
})
console.log(aa); // [1, 2, 3]

甚至,压缩空缺并删除Undefined和null元素,可以这样使用filter():

1
2
3
4
5
var a = [1, 2, 3, undefined, null, 6]
var aaa = a.filter(function(x) {
return x !== undefined && x != null;
})
console.log(aaa); // [1, 2, 3, 6]

every()和some()

every()和some()方法是数组的逻辑判定:它们对数组元素应用指定的函数进行判定,返回true或者false。

  1. every()方法就像数学中的‘针对所有” 的量词:当且仅当针对数组中的所有元素调用判定函数都返回true,它才返回true :
1
2
3
4
5
6
7
8
var a = [1, 2, 3, 4, 5, 5];
console.log(a.every(function(x) {
return x < 10;
})); // true 所有的值都小于10

console.log(a.every(function(x) {
return x < 5;
})); // false 不是所有的值都小于5
  1. some()方法就像数学中的“存在” 的量词:当数组中至少有一个元素调用判定函数返回true,它就返回true;并且当且仅当数值中的所有元素调用判定函数都返回false,它才返回false:
1
2
3
4
5
6
7
var a = [1, 2, 3, 4, 5, 5];
console.log(a.some(function(x) {
return x == 10;
})); // false a中元素没有等于10的
console.log(a.some(function(x) {
return x % 2 == 0;
})); // true a中包含有偶数

注意:一旦every()和some()确认该返回什么值它们就会停止遍历数组元素。some()在判定函数第一次返回true后就返回true,但如果判定函数一直返回false, 它将会遍历整个数组。every( )恰好相反:它在判定函数第一次返回false后就返回false,但如果判定函数一直返回true,它将会遍历整个数组。注意,根据数学上的惯例,在空数组上调用时,every()返回true,some()返回false。

reduce()和reduceRight()

reduce()和reduceRight()方法使用指定的函数将数组元素进行组合,生成单个值,这在函数式编程中是常见的操作,也可以称为“注入”和“折叠”。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
var a = [1, 2, 3, 4, 5, 5];
var sum = a.reduce(function(x, y) {
return x + y;
}, 0);
console.log(sum); // 20 数组求和
var product = a.reduce(function(x, y) {
return x * y;
}, 1);
console.log(product); // 600 数组求积
var max = a.reduce(function(x, y) {
return (x > y) ? x : y
});
console.log(max); // 5 求最大值

reduce()需要两个参数,第一个是执行化简操作的函数,化简函数的任务就是用某种方法把两个值组合或化简为一个值,并返回化简后的值,在上面的例子中,函数通过加法、乘法、或取最大值的方法组合两个值。第二个(可选)的参数是一个传递给函数的初始值。

reduce()使用的函数与forEach( )和map( )使用的函数不同。比较熟悉的是,数组元素、元素的索引和数组本身将作为第2~4个参数传递给函数。第一个参数是到目前为止的化简操作累积的结果。第一次调用函数时,第一个参数是一个初始值,它就是传递给reduce()的第二个参数。在接下来的调用中,这个值就是上一次化简函数的返回值。在上面的第一个例子中,第一次调用化简函数时的参数是0和1。将两者相加并返回1。再次调用时的参数是1和2,它返回3。然后它计算3+3=6、6+4=10, 最后计算10+5=15。最后的值是15,reduce()返回这个值。

可能已经注意到了,上面第三次调用reduce()时只有一个参数:没有指定初始值。当不指定初始值调用reduce()时,它将使用数组的第一个 元素作为其初始值。这意味着第一次调用化简函数就使用了第一个和第二个数组元素作为其第一个和第二个参数。在上面求和与求积的例子中,可以省略初始值参数。

在空数组上,不带初始值参数调用reduce()将导致类型错误异常。如果调用它的时候只有一个值——数组只有一个元素并且没有指定初始值,或者有一个空数组并且指定一个初始值——reduce()只是简单地返回那个值而不会调用化简函数。

1
2
3
4
5
6
7
8
9
10
11
var a = [0];
var sum = a.reduce(function(x, y) {
return x + y;
});
console.log(sum); //0

var a = [];
var sum = a.reduce(function(x, y) {
return x + y;
}, 0);
console.log(sum); //0
1
2
3
4
5
var a = [];
var sum = a.reduce(function(x, y) {
return x + y;
});
console.log(sum); //报错

报错:
在这里插入图片描述

reduceRight()的工作原理和reduce()-样,不同的是它按照数组索引从高到低(从右到左)处理数组,而不是从低到高。如果化简操作的优先顺序是从右到左,你可能想会使用它。

indexOf()和lastIndexOf()

indexOf()和lastIndexOf()搜索整个数组中具有给定值的元素,返回找到第一个元素的索引或者如果没有找到就返回-1。indexOf()从头至尾搜索,而lastIndexOf()则反向搜索。

1
2
3
4
var a = [0, 1, 2, 3, 1, 0];
console.log(a.indexOf(1)); // 1 a[1]是1
console.log(a.lastIndexOf(1)); // 4 a[4]是1
console.log(a.indexOf(4)); // -1 a中没有4

不同于本节描述的其他方法,index0f()和lastIndex0f()方法 不接收一个函数作为其参数。第一个参数是需要搜索的值,第二个参数是可选的:它指定数组中的一个索引,从那里开始搜索。如果省略该参数,index0f()从头开始搜索,而lastIndex0f()从末尾开始搜索。第二个参数也可以是负数,它代表相对数组末尾的偏移量,对于splice()方法:例如,- 1指定数组的最后一个元素。

如下函数在一个数组中搜索指定的值并返回包含所有匹配的数组索引的一个数组。它展示了如何运用indexOf()的第二个参数来查找除了第一个以外匹配的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//在数组a中查找所有出现的x,并且返回一个包含匹配索引的数组
function find(a, x) {
var result = []; //将会返回的数组
var len = a.length; //待搜索数组的长度
var pos = 0; //开始搜索的位置
while (pos < len) { //循环搜索多个数组
pos = a.indexOf(x, pos); //搜索
if (pos === -1) break; //未找到,就完成搜索
result.push(pos); //否则,在数组中存储索引
pos++; //并从下一个位置开始
}
return result; //返回包含索引的数组
}
var a = [3, 4, 32, 2, 2, 1, 4, 5, 3, 2];
console.log(find(a, 2));

注意:字符串也有indexOf()和lastIndexOf()方法,它们和数组方法的功能类似。




愿你的坚持终有收获。