面试官:你可以用 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)
}

全部评论

相关推荐

点赞 评论 收藏
分享
在校生实习:我觉得平时学校肯定有各种大作业吧。包装一下写项目里。特长那块喧宾夺主了,项目肯定是大头。特长里比如:熟悉vscode,这个感觉不具有吸引性。简要介绍你会什么语言,什么工具等就行了。同26找实习,我是个超级菜鸡😭大家一起加油
点赞 评论 收藏
分享
点赞 1 评论
分享
牛客网
牛客企业服务