JavaScript中的for...of和for...in循環(huán)容易遇到的問題及解決方法總結(jié)
兩者的區(qū)別:
- 適用對(duì)象類型:
- for...of:主要用于遍歷可迭代對(duì)象(例如數(shù)組、字符串、Set、Map等),可以獲取到迭代對(duì)象的值。
- for...in:主要用于遍歷對(duì)象的屬性(包括原型鏈上的屬性),可以獲取到屬性名(鍵)。
- 遍歷順序:
- for...of:按照對(duì)象的順序迭代,一般用于遍歷有序集合。
- for...in:無法保證屬性的遍歷順序,可能會(huì)導(dǎo)致屬性的無序輸出。
- 迭代內(nèi)容:
- for...of:迭代的是對(duì)象的值本身,例如數(shù)組中的元素、字符串中的字符等。
- for...in:迭代的是對(duì)象的屬性名,需要通過屬性名訪問屬性值。
- 支持情況:
- for...of:在 ES6 中引入,適用于可迭代對(duì)象,如數(shù)組、字符串等。
- for...in:在早期版本的 JavaScript 中就存在,用于遍歷對(duì)象的屬性。但是不適用于數(shù)組等可迭代對(duì)象,因?yàn)樗鼤?huì)遍歷出額外的屬性。
- 性能:
- for...of:通常性能比 for...in 更好,因?yàn)樗恍枰闅v原型鏈上的屬性。
示例代碼演示兩者的不同用法:
// for...of 遍歷數(shù)組 const arr = [1, 2, 3, 4]; for (const element of arr) { console.log(element); // 輸出數(shù)組的每個(gè)元素 } // for...in 遍歷對(duì)象的屬性 const obj = { a: 1, b: 2, c: 3 }; for (const key in obj) { console.log(key); // 輸出屬性名 a, b, c console.log(obj[key]); // 輸出屬性值 1, 2, 3 } // for...of 遍歷數(shù)組 const arr = [1, 2, 3, 4]; for (const element of arr) { console.log(element); // 輸出數(shù)組的每個(gè)元素 } // for...in 遍歷對(duì)象的屬性 const obj = { a: 1, b: 2, c: 3 }; for (const key in obj) { console.log(key); // 輸出屬性名 a, b, c console.log(obj[key]); // 輸出屬性值 1, 2, 3 }
總之,如果你想遍歷數(shù)組或其他可迭代對(duì)象的值,使用 for...of;如果你想遍歷對(duì)象的屬性,使用 for...in。
for...of 遍歷數(shù)組的陷阱:
當(dāng)使用 for...of
循環(huán)來遍歷數(shù)組時(shí),我們通常是為了遍歷數(shù)組的元素,而不是索引。然而,在使用 for...of
循環(huán)時(shí),有一些常見陷阱需要避免,特別是關(guān)于循環(huán)索引和遍歷順序的問題。下面是如何正確使用 for...of
循環(huán)來遍歷數(shù)組,以及如何避免這些陷阱的解釋:
1. 遍歷元素而非索引: 使用 for...of
循環(huán)時(shí),我們直接遍歷數(shù)組的元素,而不需要關(guān)心索引的細(xì)節(jié)。這樣可以使代碼更加簡(jiǎn)潔易讀。例如:
const array = [1, 2, 3, 4, 5]; for (const element of array) { console.log(element); // 輸出數(shù)組的每個(gè)元素 }
2. 避免使用索引: 避免在 for...of
循環(huán)中使用額外的索引變量,因?yàn)?nbsp;for...of
循環(huán)本身已經(jīng)直接提供了數(shù)組的每個(gè)元素。這有助于減少代碼復(fù)雜性和錯(cuò)誤的機(jī)會(huì)。不推薦的寫法:
const array = [1, 2, 3, 4, 5]; for (let i = 0; i < array.length; i++) { console.log(array[i]); // 避免這種額外使用索引的方式 }
3. 保持遍歷順序: for...of
循環(huán)保證按照數(shù)組中的順序進(jìn)行遍歷,因此它適用于需要按順序處理元素的場(chǎng)景。這確保了元素的處理順序與它們?cè)跀?shù)組中的位置一致。
4. 不會(huì)遍歷稀疏元素: for...of
循環(huán)不會(huì)遍歷數(shù)組中的稀疏元素(未賦值的元素),只會(huì)遍歷有實(shí)際值的元素。這有助于避免不必要的處理。
5. 適用于可迭代對(duì)象: 除了數(shù)組,for...of
循環(huán)還適用于其他可迭代對(duì)象,如字符串、Set、Map 等。這使得代碼具有更廣泛的適用性。
綜上所述,使用 for...of
循環(huán)來遍歷數(shù)組是一種更直觀、簡(jiǎn)潔的方式,可以避免許多在傳統(tǒng) for
循環(huán)中容易犯的錯(cuò)誤。通過專注于元素而非索引,保持遍歷順序,并充分利用循環(huán)的簡(jiǎn)潔性,我們可以提高代碼的可讀性和可維護(hù)性,減少錯(cuò)誤的風(fēng)險(xiǎn)。
for...in 遍歷對(duì)象的不可靠性:
在使用 for...in
循環(huán)時(shí),可能會(huì)遇到一些問題,其中包括遍歷順序的不確定性和遍歷到原型屬性的風(fēng)險(xiǎn)。下面是對(duì)這些問題的探討:
1. 遍歷順序的不確定性: for...in
循環(huán)無法保證遍歷對(duì)象屬性的順序。這是因?yàn)閷?duì)象屬性在 ECMAScript 規(guī)范中被定義為無序的。因此,使用 for...in
循環(huán)來依賴屬性遍歷的特定順序是不可靠的。
2. 遍歷到原型屬性的風(fēng)險(xiǎn): for...in
循環(huán)會(huì)遍歷對(duì)象自身屬性以及繼承自原型鏈的屬性。這可能會(huì)導(dǎo)致意外的屬性遍歷,尤其是當(dāng)我們只想遍歷對(duì)象自身的屬性時(shí)。
3. 原型屬性被遍歷:
function Person() { this.name = 'Alice'; } Person.prototype.age = 30; const person = new Person(); for (const prop in person) { console.log(prop); // 輸出 'name' 和 'age' }
或
/** * @param {Function} fn * @return {Array} */ array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] fn = function (n) { return String(n > 5); } Array.prototype.groupBy = function (fn) { const myMap = new Map(); const keys = Object.keys(this); console.log(keys); for (const key in keys) { if (myMap.has(fn(this[key])) ) { myMap.set(fn(this[key]), myMap.get(fn(this[key])).concat([this[key]])); } else { myMap.set(fn(this[key]), [this[key]]); } } const myObj = {}; for (const [key, value] of myMap) { myObj[key] = value; } return myObj; }; array.groupBy(fn); /** * [1,2,3].groupBy(String) // {"1":[1],"2":[2],"3":[3]} */
4. 使用 hasOwnProperty 過濾原型屬性:
for (const prop in person) { if (person.hasOwnProperty(prop)) { console.log(prop); // 僅輸出 'name' } }
5. 遍歷可枚舉屬性:
Object.defineProperty(person, 'country', { value: 'USA', enumerable: true }); for (const prop in person) { console.log(prop); // 輸出 'name'、'age' 和 'country' }
6. 遍歷不可枚舉屬性:
Object.defineProperty(person, 'address', { value: '123 Main St', enumerable: false }); for (const prop in person) { console.log(prop); // 僅輸出 'name' 和 'age' }
7. 遍歷順序問題:
const obj = { a: 1, b: 2, c: 3 }; for (const prop in obj) { console.log(prop); // 輸出 'a'、'b' 和 'c',但順序不確定 }
8. 遍歷字符串屬性:
const str = 'Hello'; for (const char in str) { console.log(char); // 輸出 '0'、'1'、'2'、'3' 和 '4' }
綜上所述,盡管 for...in
循環(huán)在某些情況下可以派上用場(chǎng),但要特別小心遍歷順序的不確定性和遍歷到原型屬性的風(fēng)險(xiǎn)。在需要遍歷對(duì)象屬性時(shí),推薦使用 Object.keys
、Object.values
或 Object.entries
等方法,以獲得更可靠的遍歷結(jié)果?;蛘?,考慮使用 for...of
循環(huán)來遍歷數(shù)組和可迭代對(duì)象,以避免這些問題。
以上就是JavaScript中的for...of和for...in循環(huán)容易遇到的問題及解決方法總結(jié)的詳細(xì)內(nèi)容,更多關(guān)于JavaScript for...of和for...in循環(huán)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
js+canvas實(shí)現(xiàn)繪制正方形并插入文字效果(居中顯示)
canvas是一個(gè)可以讓我們使用腳本繪圖的標(biāo)簽,它提供了一系列完整的屬性和方法,下面這篇文章主要給大家介紹了js+canvas實(shí)現(xiàn)繪制正方形并插入文字居中顯示效果的相關(guān)資料,需要的朋友可以參考下2023-11-11Javascript實(shí)現(xiàn)關(guān)聯(lián)數(shù)據(jù)(Linked Data)查詢及注意細(xì)節(jié)
DBpedia對(duì)Wikipedia的數(shù)據(jù)變成Linked Data形式,使得機(jī)器也能讀懂并自由獲得這些數(shù)據(jù);本文的主要目的是利用Javascript從DBpedia中獲取我們想要的數(shù)據(jù),感興趣的朋友可以參考下,希望可以幫助到你2013-02-02JS獲取字符串實(shí)際長(zhǎng)度(包含漢字)的簡(jiǎn)單方法
下面小編就為大家?guī)硪黄狫S獲取字符串實(shí)際長(zhǎng)度(包含漢字)的簡(jiǎn)單方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-08-08echarts實(shí)現(xiàn)3d柱狀圖的2種方式舉例
echarts3D效果柱狀圖的實(shí)現(xiàn),這個(gè)太難了,我花了兩天終于調(diào)成我想要的效果啦,要是官網(wǎng)上有例子就好了,太難調(diào)了,下面這篇文章主要給大家介紹了關(guān)于echarts實(shí)現(xiàn)3d柱狀圖的2種方式,需要的朋友可以參考下2023-02-02微信小程序?qū)崙?zhàn)之頂部導(dǎo)航欄(選項(xiàng)卡)(1)
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崙?zhàn)之頂部導(dǎo)航欄的相關(guān)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04JS滾輪控制圖片縮放大小和拖動(dòng)的實(shí)例代碼
本文通過實(shí)例代碼給大家介紹了js 滾輪控制圖片縮放大小和拖動(dòng),代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2018-11-11mui js控制開關(guān)狀態(tài)、修改switch開關(guān)的值方法
今天小編就為大家分享一篇mui js控制開關(guān)狀態(tài)、修改switch開關(guān)的值方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-09-09