前言
ES5和ES6都新增了很多對(duì)數(shù)組遍歷的方法,本文主要介紹forEach互妓、map、filter坤塞、some冯勉、every、reduce / reduceRight摹芙、find/findIndex方法灼狰,它們可以讓我們更方便的編寫代碼,拋棄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ù)熬词。如果沒有傳入第二個(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
沒有返回值或衡。 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ù)舶担,用來綁定回調(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
方法用于過濾數(shù)組成員,滿足條件的成員組成一個(gè)新數(shù)組返回衣陶。用法和參數(shù)跟map
差不多柄瑰。與map
方法不同的是,filter
方法的回調(diào)函數(shù)需要返回等于true
或false
的值剪况。如果為true
教沾,則通過,否則译断,不通過授翻。
[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ù)堪唐,用來綁定參數(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è)值,一般用來合并數(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開始)
reduce方法如果提供了第二個(gè)參數(shù)弓熏,從0開始;否則從1開始
糠睡。 - 原數(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開始)。
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
的成員持灰,然后返回該成員。如果沒有符合條件的成員负饲,則返回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ù)洞坑,用來綁定回調(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