本系列屬于阮一峰老師所著的ECMAScript 6 入門學習筆記
Iterator(遍歷器)
JavaScript表示“集合”的數據結構,除了Array
、Object
,ES6又新增了Map
和Set
。
遍歷器(Iterator)是一種統一的接口機制,用來處理所有不同的數據結構。
Iterator的作用有三個:一位各種數據結構提供一個統一的、簡便的訪問接口;二是使得數據結構的成員能夠按照某種次序排列;三是ES6創造了一種新的命令for..of
循環,Iterator接口主要供for...of
消費
默認Iterator接口
ES6規定,默認的Iterator接口部署在數據結構的Symbol.iterator
屬性,一個數據結構只要具有Symbol.iterator
屬性,就可以認為是“可遍歷的”(iterable)。
可遍歷的數據結構具有Symbol.iterator
屬性。執行這個屬性會返回一個遍歷器對象。該對象的根本特征就是具有next
方法,每次調用next
方法都會返回一個代表當前隊員的信息對象,具有value
和done
兩個屬性。
原生具備Iterator接口的數據類型如下:
- Array
- Map
- Set
- String
- TypedArray
- 函數的arguments對象
- NodeList對象
// 原生部署Itertor接口的數據接口,不用自己寫遍歷器生成函數,可使用for...of
lelt arr = [1,2,3]
let iter = arr[Symbol.iterator]()
iter.next() // {value:1,done:false}
iter.next() // {value:2,done:false}
iter.next() // {value:3,done:false}
iter.next() // {value:undefined,done:false}// 類似對象不具備Itertor接口,需要自己部署Symbol.iterator屬性
let obj = {data: ['hello','world'],[Symbol.iterator](){const self = thislet index = 0return {next(){if(index < self.data.length){return {value: self.data[index++],done: false}}else{return {value: undefined,done:true}}}}}
}// 類數組對象(存在數值鍵名和length屬性),Symbol.iterator方法可直接引用數組的Iterator接口
NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator]
遍歷器對象的return(),throw()
遍歷器對象除了具有next
方法,還具有return
方法和throw
方法
return
方法的使用場合是:如果for...of
循環提前退出(通常是因為出錯,或者有break
語句或continue
語句,就會調用return
方法。如果一個對象在完成遍歷前需要清理或釋放資源,就可以部署return
方法)
throw
方法主要是配合Generator函數使用,一般遍歷器對象用不到這個方法
for...of循環
ES6 借鑒 C++、Java、C# 和 Python 語言,引入了for...of
循環,作為遍歷所有數據結構的統一的方法。
JavaScript提供多種遍歷語法,最原始的for
循環,比較麻煩。
數組提供內置的forEach
方法,但是無法中途跳出循環,不能使用break
或return
for...in
循環有幾個缺點:
- 數組的鍵名是數字,但是
for...in
循環是以字符串作為鍵名'0'、'2'、'3'等 for...in
不僅遍歷數字鍵名,還會遍歷Iterator 和 for...of 循環手動添加的其他鍵,甚至包括原型鏈上的鍵- 某些情況下,
for...in
循環會以任意順序遍歷鍵名
與以上遍歷相比,for...of
有一些顯著的優點
- 和
for...in
一樣簡潔,但是沒有那些缺點 - 不同于
forEach
方法,可以和break
、continue
和return
配合使用 - 提供了遍歷所有數據結構統一的操作接口