深入 ES6 系列:迭代器與 for-of 迴圈 (上)

歡迎觀看此系列新文。我們將概略介紹 JavaScript 的新版本「ECMAScript 6」,亦稱為「ES6」。

本文重點在於可巡訪各個元素的 forof 迴圈,另外還有後半段繼續介紹迭代器 (Iterator)。

es6-hiway-sign

圖片出處:https://carlosazaustre.es/blog/ecmascript-6-el-nuevo-estandar-de-javascript/

 


你都如何巡訪陣列上的每一元素?在 JavaScript 於二十年前剛出現時,你必須如下處理:

而從 ES5 開始,你可使用內建的 forEach 函式:

這樣雖然有變短一點,但還是有個缺點:你無法用 break 陳述式中斷此迴圈,也不能使用 return 陳述式從封閉函式取得回傳值。

如果能有 for– 迴圈語法可巡訪陣列的元素,不就太好了嗎?

那試試 forin 迴圈如何?

但這麼做有幾個缺點:

  • 指派到此程式碼 index 的值,都是 “0“、"1“、"2" 等字串而非實際數字。如果你不想要字串運算 ("2" + 1 == "21"),這個特性就不算方便。
  • 迴圈主體不僅會執行陣列元素,也會執行其他人所添增的 expando 屬性。舉例來說,如果你的陣列具備 myArray.name 這種可列舉的屬性,則此迴圈將搭配 index == "name" 額外執行一次。即使是在陣列的原型鏈 (Prototype chain) 上的屬性也會巡訪過。
  • 最讓人訝異的,就是此程式碼在某些情況下,其巡訪陣列元素的順序可能和你預測的不一樣。

簡單來說,forin 是為了能在純粹的舊 Object 上,針對字串鍵值的運作所設計。所以對 Array 來說就沒那麼好用。

強大的 for-of 迴圈

記得上一篇介紹文提到,ES6 將繼續相容現有的 JS 程式碼。因為有數百萬個網站都在使用 forin,有些網站也的確用在陣列上。所以若要「修正」forin 在陣列上的行為,就能達到絕佳的改進效果。而 ES6 要改善此問題的唯一方式,就是添增某些新的迴圈語法:

在上述都齊備了之後,看來似乎也沒那麼讓人印象深刻的地方。我們可以先看看 forof 是否真的這麼有戲?簡單來說:

  • 若要巡訪陣列元素,這是目前最簡單、直接的語法
  • 其可避免 forin 的所有陷阱
  • forEach() 不同,forof 可搭配 breakcontinuereturn

forin 迴圈用以巡訪物件屬性;forof 迴圈則是純粹巡訪資料 (Data),如陣列中的值。

但不止於此。

可支援 for-of 的其他集合 (Collection)

forof 不僅用於陣列,亦可用於大多數類似陣列的物件,如同 DOM 的 NodeList

亦可用於字串上,將字串當做 Unicode 字元的序列:

unicode code

這也能用在 Map 與 Set 物件上。

啥?你沒聽過 Map 與 Set 物件?這兩個是 ES6 中的新物件。我們會再透過另一篇專文說明。如果你已經在使用其他程式語言的 MapSet,應該就不會太驚訝了。

舉例來說,Set 物件可削減複製的次數:

一旦你取得 Set,也許就會想在其內容之上建構迴圈。很簡單:

Map 就有點不同了。Map  中的資料是以鍵值對 (Key-value pair) 所構成,所以你可透過解構 (Destructuring) 將「key」與「value」拆成獨立的變數:

「解構」也是 ES6 的新功能,我們亦將以另一篇文章介紹。要寫的太多了,都必須筆記一下以免忘了。

你看到這裡應該有點概念了:JS 已經具備極為不同的集合類別,而且還越來越多。forof 則是要當做吃苦耐勞的迴圈陳述式,要讓開發者能順利用在這些類別上。

forof 並無法搭配純粹的舊 Object。但如果你想迭代某一物件的屬性,則可使用 forin (也就是其功能) 或內建的 Object.keys()

 


 

看到這裡,你應該已經初步了解強大的 forof 迴圈了吧?可別錯過《深入 ES6 系列:迭代器與 for-of 迴圈 (下)》,跟大家一起看完新的「迭代器 (Iterator)」。

 

 

原文連結:ES6 In Depth: Iterators and the for-of loop

 

 

您可能也會喜歡

目前找不到相關文章

共 1 則讀者回應

  1. 參照: 深入 ES6 系列:迭代器與 for-of 迴圈 (下) | 部落格 | Mozilla Taiwan

對此文章發表回應

你的電子郵件位址並不會被公開。 必要欄位標記為 *