常常看到迭代
這個詞,那麼歸總下吧~數組
什麼是 可迭代對象:
一個對象(或它的原型鏈上的某個對象)必須有一個名字是 Symbol.iterator
的屬性數據結構
String Array Map Set
是內置可迭代的對象,由於它們的原型對象都有一個 @@iterator
方法Object
不是接收可迭代對象的API
數組的遍歷 會調用迭代器接口,因此使用到數組做爲參數的場合,都使用了遍歷器函數
Map([iterable])
WeakMap([iterable])
Set([iterable])
WeakSet([iterable])
Promise.all([iterable])
Promise.race([iterable])
Array.from([iterable])
for...in
for...of
getOwnPropertyNames
不能用 for...in
來迭代 Set, 由於 Set 中的元素沒有 key, 使用 for...of 遍歷code
迭代器 與 迭代對象的差異:
迭代器
是一種特殊的對象,每個迭代器都有一個 next()
,該方法返回一個對象,包括 value
和done
屬性對象
// 實現一個返回迭代器對象的函數 function createIterator(items){ var i = 0; return { next () { var done = (i >= items.length); var value = !done ? items[i++] : 'undefined' return { done, value } } } } const a = createIterator([1, 2, 3]); //該方法返回的最終是一個對象,包含value、done屬性。 console.log(a.next()); //{value: 1, done: false} console.log(a.next()); //{value: 2, done: false} console.log(a.next()); //{value: 3, done: false} console.log(a.next()); //{value: undefined, done: true}
可迭代 和 可枚舉的差異
舉例說明 不可迭代
let arrayLike = { 0: 'aa', 1: 'bb', 2: 'cc', length: 3 } for (var item of arrayLike) { console.log(item) // TypeError: arrayLike is not iterable } let obj = { a: 'monday', b: 'sunday' } for (var item of obj) { console.log(item) // TypeError: obj is not iterable }
上面這個例子是想遍歷一個 類數組對象
和 一個 對象
, 由於它不可迭代,因此用 for...of
不能遍歷
報錯TypeError: arrayLike is not iterable
接口
可是使用 for...in
又能夠遍歷了原型鏈
for (var item in arrayLike) { console.log(item) // 0 1 2 length } for (var item in obj) { console.log(item) // a b }
這是爲何呢?開發
附上阮一峯老師的解釋部署
對象(Object)之因此沒有默認部署Iterator接口,是由於對象的哪一個屬性先遍歷,哪一個屬性後遍歷是不肯定的,須要開發者手動指定。本質上,遍歷器是一種線性處理,對於任何非線性的數據結構,部署遍歷器接口,就等於部署一種線性轉換。不過,嚴格地說,對象部署遍歷器接口並非很必要,由於這時對象實際上被看成Map結構使用,ES5沒有Map結構,而ES6原生提供了。
以及知乎上的解答爲何for...of對象不可迭代---賀師俊回調 , 寫的很棒,一下就清晰了~get
// 幾種迭代方式 for (const k of Object.keys(obj)) ... // enumerable own keys for (const [k, v] of Object.entries(obj)) ... // enumerable own [key, value]s for (const k of Object.getOwnPropertyNames(obj)) // all own keys for (const s of Object.getOwnPropertySymbols(obj)) // all own symbols for (const k of Reflect.ownKeys(obj)) // all own keys (include symbols)