基本語法
下面列出了這幾個(gè)遍歷語法規(guī)則:
for (let index = 0; index < array.length; index++) { const element = array[index] // ... } array.forEach(element => { // ... }) for (const key in array) { // ... } for (const iterator of array) { // ... }分情況討論這幾種寫法的不同 非數(shù)字的屬性
在 JavaScript 中所有的數(shù)組都是對(duì)象,這意味著你可以給數(shù)組添加字符串屬性:
array = ["a", "b", "c"] array.test = "testing" console.log(array) // [ "a", "b", "c", test: "testing" ]
如果打印,那么這個(gè) test 也會(huì)被打印出來
在瀏覽器中,使用 console.table(array) 打印這個(gè)數(shù)組可以看到,這個(gè)對(duì)象中 test 為 index,testing 為 value;其他數(shù)組項(xiàng)的 index 值均為數(shù)字
上述提到的幾個(gè)遍歷方法中只有 for-in 循環(huán)才能夠打印出這個(gè)鍵值對(duì):
for (const key in array) { console.log(array[key]) }實(shí)際應(yīng)用的問題
通常情況下,不建議使用 for-in 來遍歷數(shù)組,除非你知道這個(gè)數(shù)組對(duì)象中沒有這樣的屬性
數(shù)組空項(xiàng)假設(shè)要遍歷的數(shù)組張這樣:array = ["a", , "c"]
// a undefined c for (let index = 0; index < array.length; index++) { const element = array[index] console.log(element) // 沒有跳過空值 } // a c array.forEach(element => { console.log(element) // 跳過空值 }) // a c for (const key in array) { console.log(array[key]) // 跳過空值 } // a undefined c for (const iterator of array) { console.log(iterator) // 沒有跳過空值 }
上面幾個(gè)遍歷方法,只有 forEach 和 for-in 遍歷會(huì)跳過空值,值得注意的是,如果空值明確設(shè)置為 undefined 如 ["a", undefined, "c"] 那么所有遍歷方法都能夠?qū)?undefined 遍歷出來
實(shí)際應(yīng)用的問題在 JSON 中是不支持這樣的空值的,如果在 parse 方法調(diào)用時(shí)傳入的 JSON 字符串?dāng)?shù)據(jù)含有空值,會(huì)報(bào)錯(cuò):
JSON.parse("["a", , "c"]") // 所以建議使用 for-of 或 for 循環(huán)進(jìn)行遍歷,因?yàn)槿绻?/pre>stringify 方法調(diào)用時(shí),空值會(huì)被轉(zhuǎn)為 null 非空值或 undefined
正確的做法應(yīng)該是保持 undefined,遍歷使用 for-of 或 for 循環(huán)
建議使用 for-of
方法 this 指向的上下文在 forEach 中需要傳入一個(gè)函數(shù),這個(gè)函數(shù)的 this 指向因語法形式而變化:
for (let index = 0; index < array.length; index++) { const element = array[index] console.log(this) // {} } array.forEach(function (element) { console.log(this) // undefined }) array.forEach(element => { console.log(this) // {} }) for (const key in array) { console.log(this) // {} } for (const iterator of array) { console.log(this) // {} }上述遍歷寫法,只有 forEach 在傳入非箭頭函數(shù)的時(shí)候會(huì)出現(xiàn)不一致的情況
建議使用箭頭函數(shù)
Async/Awaitasync 異步編程中 forEach 則不會(huì)按照預(yù)期執(zhí)行,如下:
// a undefined c {(async () => { for (const iterator of array) { const result = await new Promise(res => setTimeout(() => { res(iterator) }, 1000)) console.log(result) } })()} // a c {(async () => { for (const key in array) { const result = await new Promise(res => setTimeout(() => { res(array[key]) }, 1000)) console.log(result) } })()} // a undefined c {(async () => { for (let index = 0; index < array.length; index++) { const result = await new Promise(res => setTimeout(() => { res(array[index]) }, 1000)) console.log(result) } })()} // 語法錯(cuò)誤 {(async () => { array.forEach(element => { const result = await new Promise(res => setTimeout(() => { res(element) }, 1000)) console.log(result) }) })()}按照上述寫法 forEach 會(huì)報(bào)錯(cuò),首先看一下 forEach 的原理:
本質(zhì)上 forEach 就像一個(gè) for 循環(huán)的包裝:
Array.prototype.forEach = function (callback) { for (let index = 0; index < this.length; index++) { callback(this[index], index, this) } }如果按照上述寫法,那么在回調(diào)函數(shù)內(nèi)部調(diào)用 await 需要這個(gè)回調(diào)函數(shù)本身也是 async 函數(shù),因此改為如下寫法:
// 語法錯(cuò)誤 {(async () => { array.forEach(async element => { const result = await new Promise(res => setTimeout(() => { res(element) }, 1000)) console.log(result) }) })()}按照這樣寫法,forEach 最后會(huì)變成并行執(zhí)行,而非串行。
因此建議使用 for-of 循環(huán)
或者創(chuàng)建一個(gè) forEachAwait 方法:
async function forEachAwait(arr, cb) { for (let index = 0; index < array.length; index++) { await cb(arr[index], index, arr) } } // a undefined c {(async () => { forEachAwait(array, async (elem) => { const result = await new Promise(res => setTimeout(() => { res(elem) }, 1000)) console.log(result) }) })()}參考:For vs forEach() vs for/in vs for/of in JavaScript
歡迎訂閱我的公眾號(hào):
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/102212.html
摘要:循環(huán)方法方法不改變?cè)瓟?shù)組方法會(huì)給原數(shù)組中的每個(gè)元素都按順序調(diào)用一次函數(shù)。篩選出過濾出數(shù)組中符合條件的項(xiàng)組成新數(shù)組代碼方法方法為數(shù)組中的每個(gè)元素執(zhí)行一次函數(shù),直到它找到一個(gè)使返回表示可轉(zhuǎn)換為布爾值的值的元素。 showImg(https://segmentfault.com/img/bV2QTD?w=1600&h=500); 前言 JavaScript 發(fā)展至今已經(jīng)發(fā)展出多種數(shù)組的循環(huán)遍...
摘要:如上圖所示,本文主要闡述了的四種迭代器,,和的功能和區(qū)別動(dòng)態(tài)數(shù)組每次遍歷開始時(shí)都會(huì)重新計(jì)算一次數(shù)組的長(zhǎng)度稀疏數(shù)組不會(huì)跳過無效數(shù)組動(dòng)態(tài)數(shù)組與一樣,會(huì)遍歷到新增加的元素稀疏數(shù)組也不會(huì)跳過無效數(shù)組特點(diǎn)可以遍歷字符串可以遍歷類數(shù)組對(duì)象對(duì)象可 showImg(https://segmentfault.com/img/bV4PxL?w=3134&h=932); 如上圖所示,本文主要闡述了Array...
摘要:區(qū)別遍歷數(shù)組常用調(diào)用數(shù)組的每個(gè)元素,并將元素傳遞給回調(diào)函數(shù)這種循環(huán)的問題在于無法中途跳出循環(huán),和命令不能奏效和都返回?cái)?shù)組,返回的與原數(shù)組長(zhǎng)度相同只返回符合條件的結(jié)果一個(gè)值和返回布爾值遍歷對(duì)象所有的可枚舉屬性主要是為了遍歷對(duì)象而設(shè)計(jì)的,不適 forEach,map,filter區(qū)別 forEach 遍歷數(shù)組常用(調(diào)用數(shù)組的每個(gè)元素,并將元素傳遞給回調(diào)函數(shù)) let arr = [1,2...
摘要:缺陷是不能使用,但可以用來,適用于鏈?zhǔn)綀?chǎng)景,如,適用于全部元素的遍歷,缺陷是不知道迭代器,新特性,大家可以慢慢玩 原文鏈接 《JavaScript 數(shù)組遍歷》 參考 For-each over an array in JavaScript?Why is for(var item in list) with arrays considered bad practice in JavaSc...
摘要:場(chǎng)景檢查數(shù)組中是否含有某個(gè)東西和是對(duì)立的案例案例是否包含為對(duì)象循環(huán)遍歷效率對(duì)比參考參考原生實(shí)現(xiàn)等方法其他參考 1 遍歷數(shù)組的方法 1-1、for / while 最普通的循環(huán) 效率最高 兼容ie6tips:for循環(huán)更適用于循環(huán)的開始和結(jié)束已知,循環(huán)次數(shù)固定的場(chǎng)合;while循環(huán)更適合于條件不確定的場(chǎng)合 1-2、for in 兼容ie6,效率最差(效率可看最下面的對(duì)比) for in...
閱讀 1683·2021-11-16 11:44
閱讀 2411·2021-10-11 11:07
閱讀 4079·2021-10-09 09:41
閱讀 681·2021-09-22 15:52
閱讀 3203·2021-09-09 09:33
閱讀 2720·2019-08-30 15:55
閱讀 2295·2019-08-30 15:55
閱讀 850·2019-08-30 15:55