在 JavaScript 中,對(duì)于數(shù)組的操作非常頻繁,對(duì)應(yīng)的 API 也很豐富 。ECMAScript 規(guī)范在每一版發(fā)布時(shí),都會(huì)提供新的 API 來增強(qiáng)數(shù)組的操作能力,下面將詳細(xì)介紹這些 API 的一些特性。
ES5 新增的 9 個(gè)API
forEach( callback, [thisArg] )
在 ES5 之前,我們可以通過 for 和 for in 兩種方式來遍歷數(shù)組。
ES5 引入了一個(gè)新方法 forEach,使數(shù)組遍歷更加簡(jiǎn)潔,
forEach需要傳遞兩個(gè)參數(shù),第一個(gè)參數(shù)是回調(diào)函數(shù),是必選參數(shù),第二個(gè)參數(shù)是一個(gè)對(duì)象,用來改變 callback 中的 this 指向,是可選參數(shù)。
輸出結(jié)果:
a 0 ['a', 'b', 'c']
b 1 ['a', 'b', 'c']
c 2 ['a', 'b', 'c']
callback 中傳入了3個(gè)參數(shù) v,i,r 分別表示當(dāng)前元素、當(dāng)前位置、數(shù)組對(duì)象。
再看看使用 thisArg 的例子:
輸出結(jié)果:
a 0
b 1
c 2
不傳 thisArgs 時(shí),callback 中的 this 默認(rèn)指向 window 對(duì)象,當(dāng)傳遞 thisArg 時(shí),callback 中的 this 就指向了 thisArg.
因此這個(gè)參數(shù)的目的就是為了改變回調(diào)函數(shù)中的this指向。
對(duì)于不支持 ES5 的瀏覽器,我們可以對(duì) forEach 進(jìn)行簡(jiǎn)單的擴(kuò)展來兼容老的瀏覽器:
filter( callback , [thisArg] )
filter 是`過濾`的意思,所以這個(gè)方法的作用就是返回一個(gè)匹配過濾條件的新數(shù)組,其接收兩個(gè)參數(shù) callback 和 thisArg,callback也是回調(diào)函數(shù),主要用于對(duì)元素進(jìn)行條件匹配,thisArg 和 forEach中的 thisArg 作用一樣,在這里就不重復(fù)了,看下面示例:
打印newArr結(jié)果 ["a", "a"]
沒有filter的時(shí)候,要實(shí)現(xiàn)這個(gè)功能,我們事先要?jiǎng)?chuàng)建一個(gè)空的數(shù)組,把匹配到的元素再 push 進(jìn)去,現(xiàn)在就不需要那么麻煩了,我們?cè)倏纯磳?duì)filter的擴(kuò)展:
可以看出,filter 將過濾的結(jié)果作為一個(gè)新數(shù)組返回,即使符合條件的元素只有一個(gè),返回的也是數(shù)組 。為了更方便的對(duì)單個(gè)元素進(jìn)行查詢,ES6 在數(shù)組原型上提供了 find 方法,用于從數(shù)組中查詢單個(gè)符合條件的元素,和 filter 不同的是,它返回的是單個(gè)元素。
[2, 3, 5, 8, 9, 3].find(item => item == 3); // 3
需要注意的是,find 只返回第一個(gè)匹配到的元素,如果沒有匹配到,則會(huì)返回 undefined 。和 filter 一樣,find 也可以傳遞第 2 個(gè)參數(shù),用于設(shè)置回調(diào)函數(shù)的 this 指針 。
map( callback, [thisArg] )
map 的作用是對(duì)原數(shù)組進(jìn)行加工處理后并將其作為一個(gè)新數(shù)組返回,該方法同樣接收兩個(gè)參數(shù),callback 是回調(diào)函數(shù)用于對(duì)數(shù)組進(jìn)行加工處理,thisArg 和上面的一樣。先看一個(gè)簡(jiǎn)單的例子:
打印newArr[0] 結(jié)果:{w: 10, h: 10, area: 100}
可以看出,newArr 返回的是增加了 area 屬性的對(duì)象數(shù)組。這個(gè)方法非常實(shí)用,一般情況下,當(dāng)一個(gè)ajax請(qǐng)求返回時(shí),我們都要對(duì)其結(jié)果集進(jìn)行過濾和校驗(yàn)等操作,這時(shí) map 就派上用場(chǎng)了。我們?cè)倏纯慈绻麑?duì) map 進(jìn)行兼容性擴(kuò)展:
reduce ( callback, [initialValue] )
reduce 在這里有`減少`的意思,其作用是對(duì)數(shù)組進(jìn)行歸并操作,換句話說就是對(duì)數(shù)組每一個(gè)元素進(jìn)行累加,最終返回所有元素之和。 回調(diào)函數(shù) callback 接收4個(gè)參數(shù):
previousValue - 存放的是上一次callback返回的結(jié)果,其初始值默認(rèn)為數(shù)組的第一個(gè)元素。
currentValue - 是當(dāng)前元素 。默認(rèn)從數(shù)組的第二個(gè)元素開始。
currentIndex - 是當(dāng)前元素位置 。
array - 是當(dāng)前數(shù)組。
輸出結(jié)果:
1 2 1
3 3 2
6 4 3
打印newArr ---> 10
reduce 除過可以傳遞 callback 之外,還可以傳遞一個(gè)參數(shù) initialValue ,作為數(shù)組累加的基數(shù)。當(dāng)傳了這個(gè)參數(shù)以后,callback 中的 previousValue 初始值就被置為 initialValue,reduce 也改為從數(shù)組的第一個(gè)元素開始遍歷。
輸出結(jié)果:
100 1 0
101 2 1
103 3 2
106 4 3
打印newArr ---> 110
從結(jié)果可以看出,reduce 最終返回的是: previousValue + 數(shù)組本身歸并計(jì)算的結(jié)果。對(duì) reduce 的 polyfill 實(shí)現(xiàn)如下:
reduceRight ( callback, [initialValue] )
和 reduce 的作用完全相同,唯一的不同是,reduceRight 是從右至左遍歷數(shù)組的元素。
some ( callback, [thisArg] )
some 是`某些、一些`的意思,其作用是對(duì)數(shù)組中的每一項(xiàng)執(zhí)行回調(diào)函數(shù),如果該函數(shù)對(duì)任一項(xiàng)返回 true,則停止遍歷,并返回 true 。
輸出結(jié)果:
1 0 [1, 2, 3, 4]
2 1 [1, 2, 3, 4]
3 2 [1, 2, 3, 4]
打印 result ---> true
some 檢測(cè)整個(gè)數(shù)組,只要當(dāng)arr中有一個(gè)元素符合條件 item>2 就停止檢測(cè)和遍歷,并返回 true,以表示檢測(cè)到目標(biāo)。這和我們?cè)?for 循環(huán)中使用 break 語言的作用有點(diǎn)類似。
對(duì)于 some 的兼容性擴(kuò)展如下:
every (callback, [thisArg])
every 是`每一個(gè)`的意思,其作用是對(duì)數(shù)組中的每一項(xiàng)執(zhí)行回調(diào)函數(shù),如果該函數(shù)對(duì)每一項(xiàng)都返回 true,則返回 true 。
輸出結(jié)果:
1 0 [1, 2, 3, 4]
2 1 [1, 2, 3, 4]
3 2 [1, 2, 3, 4]
打印result ---> false
當(dāng)檢測(cè)第3個(gè)元素時(shí),item<3 為 false,停止檢測(cè),并返回 false,這說明every在檢測(cè)元素時(shí),要求每一個(gè)元素都要符合條件 item<3,如果有一個(gè)不符合就停止檢測(cè),并返回false。(你可以測(cè)試 item<5 時(shí)的運(yùn)行結(jié)果,返回值一定是 true ) 。
那 every 到底有什么作用呢? 當(dāng)一個(gè) for 循環(huán)使用了 break 語句后,我們想知道 for 循環(huán)是否正常的執(zhí)行完時(shí), 我們一般會(huì)通過檢測(cè)for中的索引 i==arr.length 來判斷,因此every 的作用就體現(xiàn)在這里。
下面是對(duì)于 every 的兼容性擴(kuò)展:
indexOf[searchElement, [fromIndex]]
indexOf() 用于查詢數(shù)組元素對(duì)應(yīng)的索引位置,可以傳遞兩個(gè)參數(shù),第一個(gè)參數(shù)是要匹配的元素,必須是簡(jiǎn)單數(shù)據(jù)類型。第二個(gè)參數(shù)是指定查詢的起始位置。
// 默認(rèn)從索引0的位置開始
[1, 2, 3, 5, 2].indexOf(2);// 1
// 指定從索引3的位置開始
[1, 2, 3, 5, 2].indexOf(2, 3);// 4
ndexOf() 返回的是元素在數(shù)組中的位置 。如果只想知道數(shù)組中是否存在某個(gè)元素,而不關(guān)心元素的位置,也可以使用 ES6 提供的 includes() 方法來判斷。
let a = [1, 2, 3];
a.includes(1);// true
a.includes(1, 1);// false
includes() 也是數(shù)組原型上的方法, 和 indexOf() 的傳參是一樣的。
需要注意的是,indexOf() 適用于數(shù)組元素是簡(jiǎn)單類型的情況,而無法檢索對(duì)象數(shù)組的元素位置。
let arr = [{c: 1}, {c: 2}];// 對(duì)象數(shù)組
arr.indexOf({c: 1});// -1
對(duì)于這個(gè)問題,可以使用 forEach() 來遍歷數(shù)組,當(dāng)找到符合條件的元素時(shí),就可以獲取到對(duì)應(yīng)的數(shù)組下標(biāo),而在 ES6 中,可以使用 findIndex() 達(dá)到同樣的目的。
findIndex() 也是用于查詢數(shù)組元素的位置,和 indexOf() 不同的是,它可以檢索對(duì)象數(shù)組的元素位置,但需要通過回調(diào)函數(shù)來指定匹配的元素。
//簡(jiǎn)單數(shù)組
[1, 2, 3, 5].findIndex(item => item == 3);// 2
//對(duì)象數(shù)組
[{id: 1}, {id: 3}, {id: 5}].findIndex(item => item.id == 3);// 1
lastIndexOf[searchElement, [fromIndex]]
和 indexOf() 的作用完全相同,唯一的不同是,lastIndexOf() 是從右至左檢索數(shù)組元素。
感興趣的小伙伴,可以關(guān)注公眾號(hào)【grain先森】,回復(fù)關(guān)鍵詞 【181230】,獲取【前端教程】,更多關(guān)鍵詞玩法期待你的探索~