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