在 JavaScript 中,迭代是處理數據結構的常見任務。無論是遍歷陣列、字串、映射 (Map) 還是集合 (Set),都需要有效的迭代工具。ES6 中引入的 for...of 迴圈就是一個針對可迭代對象 (iterable objects) 的簡單而強大的解決方案。在這篇文章中,將介紹 for...of 迴圈的使用,並將它與 for...in 迴圈進行比較,幫助更好地理解兩者之間的區別與應用場景。
1.for...of 迴圈的基本用法
for...of 迴圈專門用來迭代可迭代對象,這類對象包括陣列 (Array)、字串 (String)、映射 (Map)、集合 (Set) 以及其他具備迭代協議的對象。與 for...in 不同,for...of 直接迭代對象中的「值」,而非屬性或鍵。
基本範例
讓我們從一個簡單的陣列範例開始:
在這個範例中,for...of 迴圈遍歷了 fruits 陣列中的每個元素,並將每個元素的值存放在變數 fruit 中。可以看到,它比傳統的 for 迴圈更簡潔,且不需要使用索引來訪問陣列元素。
2.遍歷字串
for...of 也可以用來遍歷字串中的每個字符:
這使得處理字串變得非常直觀,特別是在需要逐字符進行處理時。
3.迭代其他可迭代對象
除了陣列和字串,for...of 還能夠迭代其他可迭代對象,例如 Map 和 Set。
遍歷 Map
Map 是 JavaScript 中的一種鍵值對結構,我們可以使用 for...of 來同時遍歷它的鍵和值:
在這裡,我們使用解構賦值來直接獲取每個鍵值對的鍵與值,這讓代碼更加清晰易懂。
遍歷 Set
Set 是一種只存儲唯一值的結構。使用 for...of 迴圈,我們可以很方便地遍歷集合中的每個元素:
注意,Set 只會存儲唯一的值,所以即使我們在初始化時有重複的數字,遍歷時每個數字只會被顯示一次。
4.for...of 與 for...in 的比較
for...of 與 for...in 乍看之下很相似,但它們實際上有很大的不同。for...in 主要用來遍歷對象的可枚舉屬性,而不是其值。理解這一區別對正確選擇迴圈非常重要。
for...in 的使用範例
for...in 適合用來遍歷對象的屬性名(鍵),而非其具體值。例如:
在這裡,for...in 迴圈遍歷了 person 對象的屬性名,而不是屬性的值。
與 for...of 的對比
當用 for...of 來遍歷對象時,會發現它無法直接迭代對象的屬性,因為對象本身不是可迭代的。
要迭代對象的值,我們需要使用其他方法,如 Object.values() 或 Object.entries()。
兩者的應用場景
for...in 更適合遍歷對象的屬性名,通常在處理普通對象(如 POJO: Plain Old JavaScript Object)時使用。
for...of 則專門用來遍歷可迭代對象,尤其是像陣列、字串、Map、Set 等。它不會遍歷對象的鍵,僅僅處理值,這使得它在處理數據集合時特別有用。
5.注意事項
符合迭代協議的對象
for...of 迴圈只能用來遍歷符合迭代協議 (Iterable Protocol) 的對象。如果一個對象具備 [Symbol.iterator] 方法,那它就是可迭代的。我們可以手動為對象添加迭代功能,使其能夠被 for...of 使用。
與其他 ES6 特性的結合
for...of 可以與解構賦值、生成器等 ES6 特性很好地結合使用。例如,當你需要遍歷複雜結構(如嵌套陣列)時,結合這些語法特性可以使代碼更加簡潔。
6.總結
for...of 迴圈是 ES6 引入的一個強大工具,專門用來迭代可迭代對象,無論是陣列、字串,還是像 Map 和 Set 這樣的數據結構。與 for...in 迴圈不同,for...of 迴圈專注於值的迭代,而不是屬性名。理解兩者之間的區別,並根據具體需求選擇合適的迴圈結構,能夠讓代碼更高效、簡潔。