前言
ES5和ES6都新增了很多對(duì)數(shù)組遍歷的方法,本文主要介紹forEach、map、filter、some、every、reduce / reduceRight、find/findIndex方法,它們可以讓我們更方便的編寫(xiě)代碼,拋棄for循環(huán)。而這些方法有個(gè)共同的特點(diǎn)都是不改變?cè)械臄?shù)組。
forEach
forEach是最基本的方法,它的作用是對(duì)數(shù)組的每個(gè)元素執(zhí)行一次提供的函數(shù)。
function log(element, index, array) {
console.log('[' + index + '] = ' + element);
}
[2, 5, 9].forEach(log);
// [0] = 2
// [1] = 5
// [2] = 9
forEach方法中的回調(diào)函數(shù)會(huì)被依次傳入三個(gè)參數(shù):
- 數(shù)組當(dāng)前項(xiàng)的值
- 數(shù)組當(dāng)前項(xiàng)的索引
- 數(shù)組對(duì)象本身
forEach方法除了可以傳入回調(diào)函數(shù)外,還可以傳入第二個(gè)參數(shù)。如果給forEach傳遞了第二個(gè)參數(shù),回調(diào)函數(shù)里的this將指向這個(gè)參數(shù)。如果沒(méi)有傳入第二個(gè)參數(shù),則this指向全局對(duì)象(在瀏覽器是為window),嚴(yán)格模式下是undefined。
var out = [];
[1, 2, 3].forEach(function(elem) {
this.push(elem * elem);
}, out);
out // [1, 4, 9]
map
map方法的作用就是將原數(shù)組按照一定的規(guī)則映射成一個(gè)新的數(shù)組。再將其返回,返回的是一個(gè)新的數(shù)組,而不是將原數(shù)組直接改變。forEach和map的區(qū)別在于,forEach沒(méi)有返回值。 map需要返回值,如果不給return,默認(rèn)返回undefined。使用方法和參數(shù)都跟forEach相似。
var numbers = [1, 2, 3];
numbers.map(function (n) {
return n + 1;
});
// [2, 3, 4]
numbers
// [1, 2, 3]
map方法接受的三個(gè)參數(shù):
- 數(shù)組當(dāng)前項(xiàng)的值
- 數(shù)組當(dāng)前項(xiàng)的索引
- 數(shù)組對(duì)象本身
map方法還可以接受第二個(gè)參數(shù),用來(lái)綁定回調(diào)函數(shù)內(nèi)部的this變量(與forEach相視)。
var arr = ['a', 'b', 'c'];
[1, 2].map(function (e) {
return this[e];
}, arr)
// ['b', 'c']
filter
filter方法用于過(guò)濾數(shù)組成員,滿足條件的成員組成一個(gè)新數(shù)組返回。用法和參數(shù)跟map差不多。與map方法不同的是,filter方法的回調(diào)函數(shù)需要返回等于true或false的值。如果為true,則通過(guò),否則,不通過(guò)。
[1, 2, 3, 4, 5].filter(function (elem) {
return (elem > 3);
})
// [4, 5]
filter方法的參數(shù)函數(shù)可以接受三個(gè)參數(shù):當(dāng)前成員,當(dāng)前位置和整個(gè)數(shù)組。
[1, 2, 3, 4, 5].filter(function (elem, index, arr) {
return index % 2 === 0;
});
// [1, 3, 5]
filter方法還可以接受第二個(gè)參數(shù),用來(lái)綁定參數(shù)函數(shù)內(nèi)部的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]
some & every
這兩個(gè)方法類似“斷言”(assert),返回一個(gè)布爾值,表示判斷數(shù)組成員是否符合某種條件。
-
every:數(shù)組中是否每個(gè)元素都滿足指定的條件 -
some:數(shù)組中是否有元素滿足指定的條件
every方法是所有成員的返回值都是true,整個(gè)every方法才返回true,否則返回false。
var arr = [1, 2, 3, 4, 5];
arr.every(function (elem, index, arr) {
return elem >= 3;
});
// false
some方法是只要一個(gè)成員的返回值是true,則整個(gè)some方法的返回值就是true,否則返回false。
var arr = [1, 2, 3, 4, 5];
arr.some(function (elem, index, arr) {
return elem >= 3;
});
// true
注意: 對(duì)于空數(shù)組,some方法返回false,every方法返回true,回調(diào)函數(shù)都不會(huì)執(zhí)行。
function isEven(x) {
return x % 2 === 0
}
[].some(isEven) // false
[].every(isEven) // true
reduce / reduceRight
reduce方法和reduceRight方法依次處理數(shù)組的每個(gè)成員,最終累計(jì)為一個(gè)值,一般用來(lái)合并數(shù)組的值。它們的差別是,reduce是從左到右處理(從第一個(gè)成員到最后一個(gè)成員),reduceRight則是從右到左(從最后一個(gè)成員到第一個(gè)成員),其他完全一樣。
var a = [1, 2, 3, 4, 5].reduce(function (a, b) {
console.log(a, b);
return a + b;
})
console.log(a) // 15
// 1 2
// 3 3
// 6 4
// 10 5
//最后結(jié)果:15
reduce方法和reduceRight方法的第一個(gè)參數(shù)都是一個(gè)函數(shù)。該函數(shù)接受以下四個(gè)參數(shù)。
- 累積變量,默認(rèn)為數(shù)組的第一個(gè)成員
- 當(dāng)前變量,默認(rèn)為數(shù)組的第二個(gè)成員
- 當(dāng)前位置(從0開(kāi)始)
reduce方法如果提供了第二個(gè)參數(shù),從0開(kāi)始;否則從1開(kāi)始。 - 原數(shù)組
這四個(gè)參數(shù)之中,只有前兩個(gè)是必須的,后兩個(gè)則是可選的。
var a = [1, 2, 3, 4, 5].reduce(function (a, b, c, d) {
console.log(a, b, c, d)
return a + b;
});
console.log(a) // 15
如果要對(duì)累積變量指定初值,可以把它放在
reduce方法和reduceRight方法的第二個(gè)參數(shù)(這時(shí)下標(biāo)從0開(kāi)始)。
var a = [1, 2, 3, 4, 5].reduce(function (a, b) {
return a + b;
}, 10);
console.log(a) // 25
上面的方法第二個(gè)參數(shù)相當(dāng)于提供了默認(rèn)值,由于空數(shù)組取不到初始值,reduce方法會(huì)報(bào)錯(cuò)。這時(shí),加上第二個(gè)參數(shù),就能保證總是會(huì)返回一個(gè)值。
find / findIndex
find方法,用于找出第一個(gè)符合條件的數(shù)組成員。它的參數(shù)是一個(gè)回調(diào)函數(shù),所有數(shù)組成員依次執(zhí)行該回調(diào)函數(shù),直到找出第一個(gè)返回值為true的成員,然后返回該成員。如果沒(méi)有符合條件的成員,則返回undefined。
var a = [1, 4, -5, 10].find((n) => n < 0)
var b = [1, 4, -5, 10].find((n) => n < -5)
console.log(a) // -5
console.log(b) // undefined
find方法的回調(diào)函數(shù)可以接受三個(gè)參數(shù):
- 當(dāng)前的值
- 當(dāng)前的位置
- 原數(shù)組
var a = [1, 5, 10, 15].find(function(value, index, arr) {
return value > 9;
})
console.log(a) // 10
findIndex方法的用法與find方法非常類似,返回第一個(gè)符合條件的數(shù)組成員的位置,如果所有成員都不符合條件,則返回-1。
var a = [1, 4, -5, 10].findIndex((n) => n < 0)
var b = [1, 4, -5, 10].findIndex((n) => n < -5)
console.log(a) // 2
console.log(b) // -1
這兩個(gè)方法都可以接受第二個(gè)參數(shù),用來(lái)綁定回調(diào)函數(shù)的this對(duì)象。
function f(v){
return v > this.age;
}
let person = {name: 'John', age: 20};
var a = [10, 12, 26, 15].find(f, person);
console.log(a) // 26
另外,這兩個(gè)方法都可以發(fā)現(xiàn)NaN,彌補(bǔ)了數(shù)組的indexOf方法的不足。
[NaN].indexOf(NaN)
// -1
[NaN].findIndex(y => Object.is(NaN, y))
// 0