ECMAScript 6 草案规范已经为现代 JavaScript 开发者带来了许多喜悦。在之前的博文中,我们介绍了一些新的集合类和 for..of
迭代循环。在这篇博文中,我们将讨论与 for..of
循环密切相关的内容:生成器函数。
已经有大量优秀的资料介绍了使用生成器的原因和方法。简而言之,生成器是用于创建迭代器的特殊函数,而迭代器是具有 next()
方法(可被调用来获取值)的对象。在生成器函数中,关键字 yield
为 next()
提供值。使用 yield
会挂起生成器函数的执行,保留状态,直到再次调用 next()
,此时代码会重新开始并继续,直到它 yield
另一个值(或直到生成器函数终止)。生成器函数有几个规范的用例,例如使用它们对斐波那契序列中的数字进行迭代。
介绍完基础知识后,我们通过 JavaScript 示例深入学习,该示例介绍了使用生成器的一些陷阱(或称“细枝末节”)。本书包含大量注释,您可以在阅读代码前先试用当前版本的代码:
那么,从代码中可以学到什么要点呢?
首先,构建生成器会生成具有自己独特状态的唯一迭代器,您可以将参数传递给可以控制行为的生成器构造函数。
其次,您可以在调用迭代器的 next()
方法时传入参数,该值将被分配给上一次迭代器调用中 yield
语句左侧的任何内容。这是改变迭代器输出的一个好方法。在这里,我们使用它来控制生成的单词是否大写。如果您想影响生成的第一个值,请通过生成器的构造函数来实现。
最后,生成器可以生成有限或无限迭代器。如果您使用的是无限迭代器,请务必设置某种基于 yield
ed 值的终止条件,很容易意外编写无限循环,尤其是在使用 for..of
进行迭代时。如果您通过调用 next()
来使用有限迭代器,则返回的对象的 .done
属性会指示迭代是否已完成。
我们希望这个示例连同网络上可用的其他资源能够带来一些兴趣,并促使您思考如何在自己的代码中使用生成器。Firefox 31 及更高版本和 Chrome 39 及更高版本原生支持生成器。Regenerator 项目为其他浏览器提供了生成器支持,您也可以选择使用 Traceur。
感谢 Erik Arvidsson 帮助审核本文。