JS數(shù)組的幾種遍歷方法

前言

最近感覺(jué)自己對(duì)數(shù)組遍歷的方法有點(diǎn)混亂荡澎,for循環(huán)蕊程、forEach( )雏搂、map( )等方法混合使用藕施,沒(méi)有一個(gè)統(tǒng)一的規(guī)范,所以就打算總結(jié)一下凸郑。

ES5中的數(shù)組遍歷方法

ES5為數(shù)組定義了5個(gè)迭代方法裳食。每個(gè)方法都接受兩個(gè)參數(shù):要在每一項(xiàng)上運(yùn)行的函數(shù)和(可選的)運(yùn)行該函數(shù)的作用域?qū)ο蟆绊?this 的值。
而傳入的函數(shù)又可以接受三個(gè)參數(shù):當(dāng)前遍歷的數(shù)組項(xiàng)的值芙沥,該項(xiàng)在數(shù)組中的位置和數(shù)組對(duì)象本身诲祸。

every( )

對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù)浊吏,如果該函數(shù)對(duì)每一項(xiàng)都返回true,則every( )返回true救氯。例如:

    let numbers = [1, 2, 3, 4];
    let everyResult = numbers.every((item, index, array)=>{
        return item > 1;
    })
    console.log(everyResult);  // 輸出 false

filter( )

即對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù)找田,然后返回該函數(shù)會(huì)返回true的項(xiàng)。從名字就看得出來(lái)着憨,這個(gè)方法是用來(lái)過(guò)濾數(shù)組項(xiàng)的墩衙,例如:

    let numbers = [1, 2, 3, 4];
    let filterResult = numbers.filter((item, index, array)=>{
        return item > 1;
    })
    console.log(filterResult);  // 輸出 [2, 3, 4]

forEach( )

對(duì)數(shù)組的每一項(xiàng)運(yùn)行給定函數(shù)。forEach方法是唯一一個(gè)沒(méi)有返回值的甲抖,純粹用來(lái)遍歷數(shù)組漆改。

    let numbers = [1, 2, 3, 4];
    numbers.forEach((item, index, array)=>{
        // 執(zhí)行某些操作
    })

map( )

對(duì)數(shù)組的每一項(xiàng)運(yùn)行給定函數(shù),返回每次函數(shù)調(diào)用的返回值組成的數(shù)組准谚。map方法就是有返回值的forEach方法挫剑,例如:

    let numbers = [1, 2, 3, 4];
    let mapResult = numbers.map((item, index, array)=>{
        return item * 2;
    })
    console.log(mapResult); // 輸出 [2, 4, 6, 8]

some( )

對(duì)數(shù)組的每一項(xiàng)運(yùn)行給定函數(shù),如果該函數(shù)對(duì)任一項(xiàng)返回true柱衔,則some( )就返回true暮顺。some和every就像 ||&&,some是只要有一項(xiàng)滿足秀存,就返回true捶码。

    let numbers = [1, 2, 3, 4];
    let someResult = numbers.some((item, index, array)=>{
        return item > 3;
    })
    console.log(someResult);  // 輸出 true

ES5的這幾個(gè)迭代方法,如果是只對(duì)item(當(dāng)前遍歷的數(shù)組項(xiàng))進(jìn)行操作或链,是不會(huì)改變?cè)瓟?shù)組的惫恼,但是也可以通過(guò)給定函數(shù)中接收的index參數(shù)來(lái)改變?cè)瓟?shù)組

除了ES5這幾個(gè)方法,還有常見(jiàn)的簡(jiǎn)單for循環(huán)和ES6的for...of澳盐。

for...of

ES6借鑒了Java祈纯、Python等語(yǔ)言,引入了for...of循環(huán)叼耙。for...of主要用來(lái)統(tǒng)一ES6多種數(shù)據(jù)結(jié)構(gòu)的遍歷方法腕窥,不僅可以遍歷數(shù)組,還可以遍歷Map筛婉、Set這兩種ES6新推出的數(shù)據(jù)結(jié)構(gòu)簇爆。只要具有iterator接口的數(shù)據(jù)結(jié)構(gòu),就可以用for...of循環(huán)來(lái)遍歷爽撒。還可以遍歷某些類似數(shù)組的對(duì)象入蛆,比如arguments對(duì)象、DOM NodeList 對(duì)象硕勿。

let numbers = [1, 2, 3, 4];
for(let item of numbers){
    console.log(item);
}
//輸出
// 1
// 2
// 3
// 4

有關(guān)ES6新特性的內(nèi)容哨毁,可以參考阮一峰老師的ES6入門教程

不推薦使用for...in來(lái)遍歷數(shù)組,只用來(lái)遍歷對(duì)象的屬性源武。

性能分析

這里主要測(cè)試一下for循環(huán)扼褪、forEach想幻、for...ofmap话浇、for...in這幾個(gè)方法遍歷一個(gè)長(zhǎng)度為100000的數(shù)組所耗費(fèi)的時(shí)間脏毯。

//測(cè)試數(shù)據(jù): arr = [1,2,3,4,...,99999,100000];

//普通for循環(huán)
console.time('普通for循環(huán)');
for(let i=0; i<arr.length; i++){

}
console.timeEnd('普通for循環(huán)')
//控制臺(tái)輸出 => 普通for循環(huán): 0.923095703125ms


//forEach循環(huán)
console.time('forEach循環(huán)');
arr.forEach((item)=>{

})
console.timeEnd('forEach循環(huán)')
//控制臺(tái)輸出 => forEach循環(huán): 1.973876953125ms


console.time('for...of循環(huán)');
for(let item of arr){

}
console.timeEnd('for...of循環(huán)')
//控制臺(tái)輸出 => for...of循環(huán): 3.5810546875ms


//for...in循環(huán)
console.time('for...in循環(huán)');
for(let item in arr){
    
}
console.timeEnd('for...in循環(huán)')
//控制臺(tái)輸出 => for...in循環(huán): 15.35693359375ms


//map循環(huán)循環(huán)
console.time('map循環(huán)');
arr.map((item) => {
    
})
console.timeEnd('map循環(huán)')
//控制臺(tái)輸出 => map循環(huán): 19.4990234375ms

可能由于電腦配置等問(wèn)題,這里你的控制臺(tái)輸出可能會(huì)不一樣凳枝,甚至你刷新一下瀏覽器抄沮,兩次的輸出也會(huì)不一致。這里map( )居然比for...in的性能還低岖瑰,印象中是for...in最低的叛买,可能是因?yàn)闇y(cè)試的次數(shù)太少,有待研究蹋订。

總結(jié)

從性能上來(lái)說(shuō)率挣,for循環(huán) > forEach > for...of > for...in > map,所以一般來(lái)說(shuō)使用for循環(huán)是性能最高的露戒,但是寫法稍微復(fù)雜了點(diǎn)椒功。但是性能好和要使用哪種遍歷方法并沒(méi)有太大關(guān)系,以現(xiàn)在的硬件水平來(lái)說(shuō)智什,這里的性能差異完全可以忽略动漾。所以一般來(lái)說(shuō),還需要考慮語(yǔ)義和功能需求荠锭。

如果你需要將數(shù)組按照給定規(guī)則轉(zhuǎn)換并返回該結(jié)果數(shù)組旱眯,就使用map

如果你需要進(jìn)行簡(jiǎn)單的遍歷证九,用 forEach 或者 for of删豺,但是 forEach 不能通過(guò)return和break語(yǔ)句來(lái)終止循環(huán),所以如果需要中途終止循環(huán)愧怜,就使用 for...of或者 for循環(huán)呀页。

如果是在遍歷數(shù)組的同時(shí),需要改變?cè)瓟?shù)組中的對(duì)應(yīng)項(xiàng)拥坛,就用for循環(huán)蓬蝶。

for...in會(huì)把數(shù)組所擁有可枚舉的屬性都遍歷一次,所以可能會(huì)有意想不到的結(jié)果渴逻,不推薦用來(lái)遍歷數(shù)組疾党。

另外的三個(gè),every( )惨奕、filter( )some( )按功能需要來(lái)使用即可竭钝。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末梨撞,一起剝皮案震驚了整個(gè)濱河市雹洗,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌卧波,老刑警劉巖时肿,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異港粱,居然都是意外死亡螃成,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門查坪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)寸宏,“玉大人,你說(shuō)我怎么就攤上這事偿曙〉” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵望忆,是天一觀的道長(zhǎng)罩阵。 經(jīng)常有香客問(wèn)我,道長(zhǎng)启摄,這世上最難降的妖魔是什么稿壁? 我笑而不...
    開(kāi)封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮歉备,結(jié)果婚禮上傅是,老公的妹妹穿的比我還像新娘。我一直安慰自己威创,他們只是感情好落午,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著肚豺,像睡著了一般溃斋。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上吸申,一...
    開(kāi)封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天梗劫,我揣著相機(jī)與錄音,去河邊找鬼截碴。 笑死梳侨,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的日丹。 我是一名探鬼主播走哺,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼哲虾!你這毒婦竟也來(lái)了丙躏?” 一聲冷哼從身側(cè)響起择示,我...
    開(kāi)封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎晒旅,沒(méi)想到半個(gè)月后栅盲,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡废恋,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年谈秫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鱼鼓。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡拟烫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蚓哩,到底是詐尸還是另有隱情构灸,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布岸梨,位于F島的核電站喜颁,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏曹阔。R本人自食惡果不足惜半开,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望赃份。 院中可真熱鬧寂拆,春花似錦、人聲如沸抓韩。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)谒拴。三九已至尝江,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間英上,已是汗流浹背炭序。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留苍日,地道東北人惭聂。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像相恃,于是被迫代替她去往敵國(guó)和親辜纲。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354