前言
在js開(kāi)發(fā)中,我們常常會(huì)遍歷對(duì)象和數(shù)組來(lái)達(dá)到求和、過(guò)濾的過(guò)程。雖然開(kāi)發(fā)中for可以解決所有場(chǎng)景,但是如果你只會(huì)for,你就太low,因?yàn)閖s的循環(huán)多達(dá)11種,而且每種遍歷的使用場(chǎng)景、遍歷效率都不盡相同,
js循環(huán)遍歷
通用遍歷場(chǎng)景
一、for循環(huán)
for是循環(huán)使用場(chǎng)景是最多的,也是最全面,幾乎所有的需要遍歷的功能,都可以通過(guò)for去實(shí)現(xiàn)。
let arr = [1, 2, 3]
for (let index = 0; index < arr.length; index++) {
const element = arr[index];
/**
* 代碼
*/
}
使用場(chǎng)景:數(shù)組遍歷
優(yōu)點(diǎn):
- 可以使用break、 continue 控制循環(huán)
- 在和let配合使用時(shí),可以不使用閉包就形成塊作用域
缺點(diǎn):
- 語(yǔ)法太麻煩,要時(shí)刻關(guān)注index索引的改變
二、for in循環(huán)
for in 用來(lái)循環(huán)遍歷當(dāng)前對(duì)象(數(shù)組)可枚舉的屬性,更適合遍歷數(shù)組,因?yàn)閒or in不是根據(jù)索引遍歷,而是根據(jù)鍵名遍歷的。
let obj = {
name: '李白',
ago: 18
}
for (const key in obj) {
if (obj.hasOwnProperty(key)) { //判斷當(dāng)前對(duì)象是否來(lái)自于原型鏈
const element = obj[key];
}
}
使用場(chǎng)景:對(duì)象遍歷
優(yōu)點(diǎn):
- 在和let配合使用時(shí),可以不使用閉包就形成塊作用域
- 可以使用break、 continue 控制循環(huán)
缺點(diǎn):
- 來(lái)自原型繼承的屬性也會(huì)遍歷出來(lái),出現(xiàn)很多不需要的屬性
- 按照隨機(jī)順序遍歷數(shù)組元素
三、for of遍歷
ES6新出語(yǔ)法,如果根據(jù)遍歷方式來(lái)描述,那么for of可以叫迭代器遍歷,因?yàn)閒or of只能對(duì)迭代器遍歷。在ES6中數(shù)組、Map、Set都存在迭代器(暫時(shí)先不講),知道for of可以遍歷數(shù)組、Map、Set就可以了。
let map = new Map([['name', '李白'], ['age', 18]])
for (var [key, val] of map) {
console.log(key, val)
}
使用場(chǎng)景:數(shù)組、Map、Set
優(yōu)點(diǎn):
- 在和let配合使用時(shí),可以不使用閉包就形成塊作用域
- 可以使用break、 continue 控制循環(huán)
- 不存在了for in的缺點(diǎn)
缺點(diǎn):
- 對(duì)于對(duì)象的遍歷不支持(可以通過(guò)其他手段)
四、forEach循環(huán)
forEach 作為Array自帶的遍歷方法,要元素給元素,要下標(biāo)給下標(biāo),但是你想在遍歷的時(shí)候中斷遍歷那么抱歉不行。
let arr = [1, 2, 3]
arr.forEach(function(item){
})
使用場(chǎng)景:數(shù)組遍歷
優(yōu)點(diǎn):
- 寫(xiě)法簡(jiǎn)便,不需要考慮index索引的變化
缺點(diǎn):
- 不能在運(yùn)行時(shí)中斷循環(huán)
特殊遍歷場(chǎng)景(數(shù)組自帶的方法)
五、map映射
通過(guò)遍歷老數(shù)組,對(duì)每個(gè)元素進(jìn)行處理,然后根據(jù)函數(shù)的返回值生成一個(gè)新的數(shù)組。就和一次函數(shù)x->y的過(guò)程一樣。但是不會(huì)改變老數(shù)組。
let arr = [1, 2, 3]
let arr2 = arr.map(function (item) {
return item + 1
})
console.log(arr2) //[ 2, 3, 4 ]
使用場(chǎng)景:數(shù)組遍歷,老數(shù)組通過(guò)某個(gè)算法生成新的數(shù)組
缺點(diǎn):
- 不能在運(yùn)行時(shí)中斷循環(huán),老數(shù)組多少數(shù)據(jù)新數(shù)組就多少
六、 filter過(guò)濾器
有時(shí)候我們會(huì)排除數(shù)組中某些不要的元素,比如去除元素中非1的元素。遍歷一個(gè)數(shù)組,如果函數(shù)返回值為true就保存該元素到新數(shù)組,否則就不保存。
let arr = [1, 2, 3, 1]
let arr2 = arr.filter(function (item) {
return item == 1
})
console.log(arr2) //[ 1, 1 ]
使用場(chǎng)景:老數(shù)組通過(guò)某個(gè)邏輯判斷,保存需要的值,去除不要的值,生成新的數(shù)組
缺點(diǎn):
- 不能在運(yùn)行時(shí)中斷循環(huán)
七、 find尋找元素
尋找一個(gè)數(shù)組中我們需要的元素,返回true就中止循環(huán),并且就得到該元素,如果沒(méi)有找到就返回undefined
let arr = ['杜甫', '白居易', '李白']
let name = arr.find(function (item) {
return item == '李1白'
})
console.log(name)
使用場(chǎng)景:根據(jù)自己的需求,從一個(gè)數(shù)組中挑選自己想要的元素
缺點(diǎn):
- 不能拿到元素索引
八、findIndex尋找索引
find雖然能夠找到元素,但是無(wú)法提供索引,在我們進(jìn)行數(shù)組的splice刪除方法時(shí)無(wú)法操作。那么findIndex就解決了問(wèn)題,對(duì)數(shù)組遍歷,返回true就中止循環(huán),得到當(dāng)前元素的數(shù)組索引,如果沒(méi)有一直沒(méi)有返回true,就返回-1
let arr = ['杜甫', '白居易', '李白']
let nameId = arr.findIndex(function (item) {
return item == '李白'
})
if (nameId != -1) {
arr.splice(nameId, 1)
console.log(arr) //[ '杜甫', '白居易' ]
}
使用場(chǎng)景:根據(jù)自己的需求,從一個(gè)數(shù)組中挑選自己想要元素的索引
九、reduce(看個(gè)人能力,因?yàn)椴蝗菀桌斫猓⑶易兓鄻?,很多大佬很看重他?/h5>
reduce像一個(gè)可擴(kuò)展的map函數(shù),但是map只可以返回一個(gè)數(shù)組,但是reduce可以是數(shù)組,也可以是值,通過(guò)數(shù)組的每個(gè)元素獲取一個(gè)期望。就比如求和,根據(jù)所有值計(jì)算一個(gè)和的期望
let arr = [1, 2, 3, 4, 5]
/**
* 第一個(gè)參數(shù):迭代的方法
* 第二個(gè)參數(shù):迭代期望的初始值
*/
let sum = arr.reduce(function (prev, cur, index, arr) {
/**
* prev:迭代元素的期望
* cur:當(dāng)前迭代的值
* index:當(dāng)前一項(xiàng)的下標(biāo)
* arr:迭代的原數(shù)組
*/
return prev + cur
}, 0)
console.log(sum)
使用場(chǎng)景:數(shù)組求和、數(shù)組降維
十、some(了解)
some遍歷數(shù)組,找到true,即返回true。查看數(shù)組中是否有真的存在。
let arr = ['杜甫', '白居易', '李白']
let hasName = arr.some(function (item) {
return item == '李白'
})
console.log(hasName) //true
使用場(chǎng)景:查看數(shù)組中是否有一個(gè)元素符合要求,有真即真
十一、every(了解)
every遍歷數(shù)組,找到false,即返回false。查看數(shù)組中是否全部為真。和some剛好相反,必須數(shù)組元素中全部為真才會(huì)返回真,
let arr = ['李白', '李白', '李白']
let hasName = arr.every(function (item) {
return item == '李白'
})
console.log(hasName)
使用場(chǎng)景:查看數(shù)組是否全部全部為真。有假即假
總結(jié)
雖然js的遍歷方式很多,但是使用起來(lái)又方便又舒適,在合適的場(chǎng)景選擇合適的遍歷方式,你會(huì)感覺(jué)事半功倍。