迭代是什麼?

常常看到迭代這個詞,那麼歸總下吧~數組

什麼是 可迭代對象

一個對象(或它的原型鏈上的某個對象)必須有一個名字是 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(),該方法返回一個對象,包括 valuedone 屬性對象

// 實現一個返回迭代器對象的函數
    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)
相關文章
相關標籤/搜索