Skip to content

Iterator(遍历器)的概念

JS 表示集合的数据结构一共 4 种,Array,Object,Map,Set。这样就需要一种统一的接口机制来处理所有的数据结构。Iterator 就是这样一种机制。 作用有三:

  • 为各种数据结构提供统一的简便的访问接口。
  • 使得数据结构的成员能够按照某种次序排列
  • ES6 创造了一种新的遍历命令 for...of 循环,Iterator 接口主要供 for...of 消费

默认 Iterator 接口

ES6 规定,默认的 Iterator 接口部署在数据结构的 Symbol.iterator 属性,或者 说,一个数据结构只要具有 Symbol.iterator 属性,就可以认为是“可遍历 的”(iterable)。

原生具备 Iterator 接口的数据结构:

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • 函数的 arguments 对象
  • NodeList 对象

调用 Iterator 接口的场合

  • 解构赋值:对数组和 Set 解构进行解构赋值时
  • 扩展运算符
  • yield*
  • 其他场合
    • for...of
    • Array.from()
    • Map(),Set(),WeakMap(),WeakSet()
    • Promise.all()
    • Promise.race()

for...of 循环

一个数据结构只要部署了 Symbol.iterator 属性它就被视为具有 Iterator 接口,就可以使用 for...of 它有一个重要的特点就是能够正确的识别 32 位 UTF-16 字符

以数组为例,JS 提供了多种遍历语法

for

forEach

数组内置提供此方法,但是无法中途跳出循环,break 或 return 命令都不能奏效。

for...in

可以遍历数组的键名但有以下缺点:

  • 数组的键名是数字,但是 for...in 循环是以字符串作为键名“0”、“1”、“2”等等。
  • for...in 循环不仅遍历数字键名,还会遍历手动添加的其他键,甚至包括原型链上的键。
  • 某些情况下, for...in 循环会以任意顺序遍历键名
  • 主要用于对象的遍历

for...of

相比于上面几种遍历做法有一些显著的优点

  • 有着同 for...in 一样的简洁语法,但是没有 for...in 那些缺点
  • 不同于 forEach 方法,它可以与 break 、 continue 和 return 配合使用
  • 提供了遍历所有数据结构的统一操作接口