首先是一些 ES2016 的术语:
ES2015 引入了Iterator
(迭代器),它表示提供了 next,return,以及 throw 三个方法的对象,具体满足以下接口:
interface Iterator<T> {
next(value?: any): IteratorResult<T>;
return?(value?: any): IteratorResult<T>;
throw?(e?: any): IteratorResult<T>;
}
这种迭代器对于迭代可用的值时很有用,比如数组的元素或者 Map 的键。如果一个对象有一个返回Iterator
对象的Symbol.iterator
方法,那么我们说这个对象是“可迭代的”。
迭代器协议还定义了一些 ES2015 中的特性像for..of
和展开运算符以及解构赋值中的数组的剩余运算的操作对象。
ES2015 也引入了"生成器",生成器是可以通过Iterator
接口和yield
关键字被用来生成部分运算结果的函数。生成器也可以在内部通过yield*
代理对与其他可迭代对象的调用。举例来说:
function* f() {
yield 1;
yield* [2, 3];
}
之前迭代器只在编译目标为 ES6/ES2015 或者更新版本时可用。此外,设计迭代器协议的结构,比如for..of
,如果编译目标低于 ES6/ES2015,则只能在操作数组时被支持。
TypeScript 2.3 在 ES3 和 ES5 为编译目标时由--downlevelIteration
编译选项增加了完整的对生成器和迭代器协议的支持。
通过--downlevelIteration
编译选项,编译器会使用新的类型检查和输出行为,尝试调用被迭代对象的[Symbol.iterator]()
方法 (如果有),或者在对象上创建一个语义上的数组迭代器。
注意这需要非数组的值有原生的
Symbol.iterator
或者Symbol.iterator
的运行时模拟实现。
使用--downlevelIteration
时,在 ES5/ES3 中for..of
语句、数组解构、数组中的元素展开、函数调用、new 表达式在支持Symbol.iterator
时可用,但即便没有定义Symbol.iterator
,它们在运行时或开发时都可以被使用到数组上.
TypeScript 2.3 添加了对异步迭代器和生成器的支持,描述见当前的TC39 提案。
异步迭代引入了AsyncIterator
,它和Iterator
相似。实际上的区别在于AsyncIterator
的next
、return
和throw
方法的返回的是迭代结果