map
- map()方法将数组的所有成员依次传入参数函数,然后把每一次的执行结果组成一个新数组返回。
var numbers = [1, 2, 3];
var newNumbers = numbers.map(function (n) {
return n + 1;
});
newNumbers // [2, 3, 4]
numbers // [1, 2, 3]
上面代码中,numbers数组的所有成员依次执行参数函数,运行结果组成一个新数组返回,原数组没有变化。
- map()方法接受一个函数作为参数。该函数调用时,map()方法向它传入三个参数:当前成员、当前位置和数组本身。
[1, 2, 3].map(function(elem, index, arr) {
return elem * index;
}); // [0, 2, 6]
上面代码中,map()方法的回调函数有三个参数,elem为当前成员的值,index为当前成员的位置,arr为原数组([1, 2, 3])。
- 如果数组有空位,map()方法的回调函数在这个位置不会执行,会跳过数组的空位。
var f = function (n) { return 'a' };
[1, undefined, 2].map(f); // ["a", "a", "a"]
[1, null, 2].map(f); // ["a", "a", "a"]
[1, , 2].map(f); // ["a", , "a"]
上面代码中,map()方法不会跳过undefined和null,但是会跳过空位。
filter
- filter()方法用于过滤数组成员,满足条件的成员组成一个新数组返回。
它的参数是一个函数,所有数组成员依次执行该函数,返回结果为true的成员组成一个新数组返回。该方法不会改变原数组。
[1, 2, 3, 4, 5].filter(function (elem) {
return (elem > 3);
}); // [4, 5]
上面代码将大于3的数组成员,作为一个新数组返回。
var arr = [0, 1, 'a', false];
arr.filter(Boolean); // [1, "a"]
上面代码中,filter()方法返回数组arr里面所有布尔值为true的成员。
- filter()方法的参数函数可以接受三个参数:当前成员,当前位置和整个数组。
[1, 2, 3, 4, 5].filter(function (elem, index, arr) {
return index % 2 === 0;
}); // [1, 3, 5]
上面代码返回偶数位置的成员组成的新数组。
- filter()方法还可以接受第二个参数,用来绑定参数函数内部的this变量。
var obj = { MAX: 3 };
var myFilter = function (item) {
if (item > this.MAX) return true;
};
var arr = [2, 8, 3, 4, 1, 3, 2, 9];
arr.filter(myFilter, obj); // [8, 4, 9]
上面代码中,过滤器myFilter()内部有this变量,它可以被filter()方法的第二个参数obj绑定,返回大于3的成员。
reducer & reduceRight()
- reduce()方法和reduceRight()方法依次处理数组的每个成员,最终累计为一个值。它们的差别是,reduce()是从左到右处理(从第一个成员到最后一个成员),reduceRight()则是从右到左(从最后一个成员到第一个成员),其他完全一样。
[1, 2, 3, 4, 5].reduce(function (a, b) {
console.log(a, b);
return a + b;
})
// 1 2
// 3 3
// 6 4
// 10 5
//最后结果:15
上面代码中,reduce()方法用来求出数组所有成员的和。reduce()的参数是一个函数,数组每个成员都会依次执行这个函数。如果数组有 n 个成员,这个参数函数就会执行 n - 1 次。
第一次执行:a是数组的第一个成员1,b是数组的第二个成员2。
第二次执行:a为上一轮的返回值3,b为第三个成员3。
第三次执行:a为上一轮的返回值6,b为第四个成员4。
第四次执行:a为上一轮返回值10,b为第五个成员5。至此所有成员遍历完成,整个方法的返回值就是最后一轮的返回值15。
- reduce()方法和reduceRight()方法的第一个参数都是一个函数。该函数接受以下四个参数。
- 累积变量。第一次执行时,默认为数组的第一个成员;以后每次执行时,都是上一轮的返回值。
- 当前变量。第一次执行时,默认为数组的第二个成员;以后每次执行时,都是下一个成员。
- 当前位置。一个整数,表示第二个参数(当前变量)的位置,默认为1。
原数组。 - 原数组。
这四个参数之中,只有前两个是必须的,后两个则是可选的。
[1, 2, 3, 4, 5].reduce(function (
a, // 累积变量,必须
b, // 当前变量,必须
i, // 当前位置,可选
arr // 原数组,可选
) {
// ... ...
- 如果要对累积变量指定初值,可以把它放在reduce()方法和reduceRight()方法的第二个参数。
[1, 2, 3, 4, 5].reduce(function (a, b) {
return a + b;
}, 10); // 25
上面代码指定参数a的初值为10,所以数组从10开始累加,最终结果为25。注意,这时b是从数组的第一个成员开始遍历,参数函数会执行5次。
建议总是加上第二个参数,这样比较符合直觉,每个数组成员都会依次执行reduce()方法的参数函数。另外,第二个参数可以防止空数组报错。
function add(prev, cur) {
return prev + cur;
}
[].reduce(add); // TypeError: Reduce of empty array with no initial value
[].reduce(add, 1); // 1
上面代码中,由于空数组取不到累积变量的初始值,reduce()方法会报错。这时,加上第二个参数,就能保证总是会返回一个值。
下面是一个reduceRight()方法的例子。
function subtract(prev, cur) {
return prev - cur;
}
[3, 2, 1].reduce(subtract) // 0
[3, 2, 1].reduceRight(subtract) // -4
上面代码中,reduce()方法相当于3减去2再减去1,reduceRight方法相当于1减去2再减去3。
- 由于这两个方法会遍历数组,所以实际上可以用来做一些遍历相关的操作。比如,找出字符长度最长的数组成员。
function findLongest(entries) {
return entries.reduce(function (longest, entry) {
return entry.length > longest.length ? entry : longest;
}, '');
}
findLongest(['aaa', 'bb', 'c']) // "aaa"
上面代码中,reduce()的参数函数会将字符长度较长的那个数组成员,作为累积值。这导致遍历所有成员之后,累积值就是字符长度最长的那个成员。
sort
- sort方法对数组成员进行排序,
默认是按照字典顺序排序
。排序后原数组将被改变
。
['d', 'c', 'b', 'a'].sort() // ['a', 'b', 'c', 'd']
[4, 3, 2, 1].sort() // [1, 2, 3, 4]
[11, 101].sort() // [101, 11]
[10111, 1101, 111].sort() // [10111, 1101, 111]
如果想让sort方法按照自定义方式排序,可以传入一个函数作为参数。
[10111, 1101, 111].sort(function (a, b) {
return a - b;
}) // [111, 1101, 10111]
上面代码中,sort的参数函数本身接受两个参数,表示进行比较的两个数组成员。如果该函数的返回值大于0,表示第一个成员排在第二个成员后面;其他情况下,都是第一个元素排在第二个元素前面。
注意:
自定义的排序函数应该返回数值,否则不同的浏览器可能有不同的实现,不能保证结果都一致。
网友评论