面試官:你可以用 for of 遍歷 Object 嗎?

本文以 用 for of遍歷 Object 爲引 來聊聊 迭代器模式

什麼是迭代器模式

迭代器模式提供一種方法順序訪問一個聚合對象中的各個元素,而又不暴露該對象的內部表示。 ——《設計模式:可複用面向對象軟件的基礎》

可以說迭代器模式就是爲了遍歷存在的。提到遍歷,大家都對那些手段耳熟能詳了,下面我們先簡單列一下各種數據類型的遍歷:

遍歷數組

  1. for 循環

  2. forEach

  3. map

  4. reduce

  5. keys

  6. values

  7. for of

  8. ......

其中keys values for of 需要Iterator支持,後面會介紹Iterator

遍歷 Map/Set

  1. keys

  2. entries

  3. forEach

  4. ......

遍歷 Object

  1. for in

  2. Object.keys(obj)得到對象每個屬性的數組, 然後使用數組的遍歷方法遍歷每個key,就能獲取 每個key 對應的value

Iterator 和 for of

Iterator是ES6提出的一個接口,爲各種不同的數據結構提供統一的訪問機制。任何數據結構只要部署 Iterator 接口,就可以完成遍歷操作。

Iterator 的作用

  1. 爲各種數據結構,提供一個統一的、簡便的訪問接口。

  2. ES6提出了新的遍歷命令for...of循環,Iterator 接口主要供for...of消費。

Iterator 的遍歷過程

既然數組是支持for...of循環的,那數組肯定部署了 Iterator 接口,我們通過它來看看Iterator 的遍歷過程。

從圖中我們能看出:

  1. Iterator 接口返回了一個有next方法的對象。

  2. 每調用一次 next,依次返回了數組中的項,直到它指向數據結構的結束位置。

  3. 返回的結果是一個對象,對象中包含了當前值value 和 當前是否結束done

用 for of 遍歷 Object

回到標題中的問題,我們現在如何去讓一個對象也可以用 for of 來遍歷它呢?

根據上面講到的內容,需要給對象也部署 Iterator 接口(其實就是在Object.prototype上實現一個以Symbol.iterator爲名的function,這個function返回一個有next方法的對象,每調用一次 next, 能夠依次返回數組中的項,直到它指向數據結構的結束位置 )

function objectIterator() {
  const keys = Object.keys(this)
  let index = 0
  return {
    next: () => {
      const done = index >= keys.length
      const value = done ? undefined : this[keys[index]]
      index++
      return {
        done,
        value
      }
    }
  }
}
Object.prototype[Symbol.iterator] = objectIterator
const obj = {
  key: '1',
  value: '2'
}
for (const iterator of obj) {
  console.log(iterator)
}
[object Object]

更多精彩請點👉:開發者網站---面試問題

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章