生成器 - 精细的图形部分

ECMAScript 6 草案规范已经为现代 JavaScript 开发者带来了许多喜悦。在之前的博文中,我们介绍了一些新的集合类和 for..of 迭代循环。在这篇博文中,我们将讨论与 for..of 循环密切相关的内容:生成器函数。

已经有大量优秀的资料介绍了使用生成器的原因和方法。简而言之,生成器是用于创建迭代器的特殊函数,而迭代器是具有 next() 方法(可被调用来获取值)的对象。在生成器函数中,关键字 yieldnext() 提供值。使用 yield 会挂起生成器函数的执行,保留状态,直到再次调用 next(),此时代码会重新开始并继续,直到它 yield 另一个值(或直到生成器函数终止)。生成器函数有几个规范的用例,例如使用它们对斐波那契序列中的数字进行迭代。

介绍完基础知识后,我们通过 JavaScript 示例深入学习,该示例介绍了使用生成器的一些陷阱(或称“细枝末节”)。本书包含大量注释,您可以在阅读代码前先试用当前版本的代码:

那么,从代码中可以学到什么要点呢?

首先,构建生成器会生成具有自己独特状态的唯一迭代器,您可以将参数传递给可以控制行为的生成器构造函数。

其次,您可以在调用迭代器的 next() 方法时传入参数,该值将被分配给上一次迭代器调用中 yield 语句左侧的任何内容。这是改变迭代器输出的一个好方法。在这里,我们使用它来控制生成的单词是否大写。如果您想影响生成的第一个值,请通过生成器的构造函数来实现。

最后,生成器可以生成有限或无限迭代器。如果您使用的是无限迭代器,请务必设置某种基于 yielded 值的终止条件,很容易意外编写无限循环,尤其是在使用 for..of 进行迭代时。如果您通过调用 next() 来使用有限迭代器,则返回的对象的 .done 属性会指示迭代是否已完成。

我们希望这个示例连同网络上可用的其他资源能够带来一些兴趣,并促使您思考如何在自己的代码中使用生成器。Firefox 31 及更高版本和 Chrome 39 及更高版本原生支持生成器。Regenerator 项目为其他浏览器提供了生成器支持,您也可以选择使用 Traceur。

感谢 Erik Arvidsson 帮助审核本文。