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 配合使用
- 提供了遍历所有数据结构的统一操作接口