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