ES6中的迭代器

220 阅读1分钟

迭代的英文是“iteration”,源自于拉丁文itero,意思是“重复”或“再来”。在软件开发中,“迭代”的意思是按照顺序反复多次执行一段代码,通常会有明确的终止条件。ES6规范中,新增了两个高级特性:迭代器和生成器。使用这两个特性,能够清晰、高效、方便的实现迭代。

在JavaScript中,计数循环就是一种最简单的迭代:

for(let i = 0; i <= 10; i++){ console.log(i); }

循环是迭代机制的基础,这是因为它可以指定迭代的次数,以及每次迭代要执行什么操作。每次循环都会在下一次迭代开始之前完成,而每次迭代的循环都是事先定义好的。

迭代会在一个有序集合上进行。(“有序”可以理解为集合中所有项都可以按照既定的顺序被遍历到,特别是对开始项和结束项有明确的定义。)数组是JavaScript中有序集合的最典型例子。

let collection = ['foo', 'bar', 'baz']; for(let index = 0; index < collection.length; ++index) { console.log(collection[index]); }

因为数组有已知的长度,且数组每一项都可以通过索引获取,所以整个数组可以通过递增索引来遍历。由于如下原因,通过这种循环来执行例程并不理想。 • 迭代之前需要知道如何使用数组结构 数组中的每一项都只能先通过引用取得数组对象,然后再通过[]操作符取得特定索引位置上的项。这种情况并不适用于所有数据结构。 • 遍历顺序并不是数据结构固有的。 通过递增索引来访问数据,是特定于数组类型的方式,并不适用于其他具有隐式顺序的数据结构。

ES5新增了Array.prototype.forEach()方法,向通用迭代需求迈进了一步(但仍然不够理想):

let collection = ['foo', 'bar', 'baz']; collection.forEach((item) => console.log(item)); //foo //bar //baz

这个方法解决了单独记录索引和通过数组对象取得值的问题。不过,没有办法标识迭代何时终止,因此这个方法只适用于数组,而且回调结构也比较笨拙。

在ECMAScript较早的版本中,执行迭代必须使用循环或其他辅助结构。随着代码量增加,代码会变得越发混乱。很多语言都通过原生语言结构解决了这个问题,开发者无须事先知道如何迭代就能实现迭代操作。这个解决方案就是迭代器模式。Python、Java、C++,还有其他很多语言都对这个模式提供了完备的支持。JavaScript在ECMAScript6 以后也支持了迭代器模式。

__内容来自红宝书第四版