迭代器, 生成器
状态: 初稿
可迭代对象
如果一个对象实现了 Symbol.iterator
属性, 就被认为是可迭代的.
有些内建类型如 Array
, Map
, Set
, String
, Int32Array
, Uint32Array
等已实现了它们的 Symbol.iterator
属性.
对象的 Symbol.iterator
函数的职责是返回要迭代的列表.
for..of
语句
for..of
调用一个可迭代对象的 Symbol.iterator
属性, 遍历它每个元素.
以 for..of
遍历一个数组:
1 | let someArray = [1, "string", false]; |
for..of
对比 for..in
for..of
和 for..in
都迭代一个列表; 但是迭代的值不一样, for..in
返回被迭代对象键的列表, 而 for..of
返回被迭代对象所有数值属性值的列表.
下例显示该差别:
1 | let list = [4, 5, 6]; |
另一点差别是 for..in
操作任何对象; 提供的是查看该对象属性的方法.for..of
则不同, 它主要关注可迭代对象储存的值. Map
和 Set
等内建对象实现 Symbol.iterator
属性来访问它们储存的值.
1 | let pets = new Set(["Cat", "Dog", "Hamster"]); |
代码生成
面向 ES5 和 ES3
当面向 ES5 或 ES3 兼容引擎, 只有 Array
类型的值允许迭代器.
用 for..of
遍历非 Array
值, 即使这些值实现了 Symbol.iterator
属性, 也是错误的.
编译器会为 for..of
循环生成简单 for
循环, 例如:
1 | let numbers = [1, 2, 3]; |
会被转换为:
1 | var numbers = [1, 2, 3]; |
面向 ECMAScript 2015 及更高版本
如果面向 ECMAScript 2015 兼容引擎, 编译器生成 for..of
以利用引擎内建的迭代器实现.