第七章主讲迭代器与生成器【ES6新增】
迭代:按照顺序反复执行一段程序,通常有明确终止条件。
for (let i = 1; i <= 10; ++i) {
console.log(i); // 计数循环是一种最简单的迭代
}
let collection = ['foo', 'bar', 'baz'];
for (let index = 0; index < collection.length; ++index) {
console.log(collection[index]); // 通过递增索引来遍历
}
遍历顺序并不是数据结构固有的,通过递增索引来访问数据是特定于数组类型的方式,并不适用于其他具有隐式顺序的数据结构。
ES5新增的Array.prototype.forEach() 没有办法标识迭代何时终止,所以依然只适用数组迭代。于是ES6有了迭代器模式。
- 迭代器模式:描述了一个方案,即可以把有些结构称为“可迭代对象”(iterable),因为它们实现了正式的 Iterable 接口,而且可以通过迭代器 Iterator 消费。
- 迭代器(Iterable)是按需创建的一次性对象,每个迭代器都会关联一个可迭代对象。Symbol.iterator 作为键。这个默认迭代器属性必须引用一个迭代器工厂
函数,调用这个工厂函数必须返回一个新迭代器。
实际写代码过程中,不需要显式调用这个工厂函数来生成迭代器,很多内置类型都实现了Iterable接口。
Array Iterator{}就是一个迭代器
next()可获得下一个值
done为true时表示“耗尽",表示迭代完了,只要迭代器到达 done: true 状态,后续调用 next()就一直返回同样的值了。
这里不用担心值就为undefined的情况,我试了一下,没有影响的
- 迭代器(Iterable)是按需创建的一次性对象,每个迭代器都会关联一个可迭代对象。Symbol.iterator 作为键。这个默认迭代器属性必须引用一个迭代器工厂
- 生成器 (Generator)
生成器是 ECMAScript 6 新增的一个极为灵活的结构,拥有在一个函数块内暂停和恢复代码执行的能力。- 生成器的形式是一个函数,函数名称前面加一个星号(*)表示它是一个生成器。只要是可以定义函数的地方,就可以定义生成器。
- yield可以实现输入输出
这个应用场景是什么呢 给我们举例了一个无穷计数生成器
注意:箭头函数不能用来定义生成器函数。
- 生成器的形式是一个函数,函数名称前面加一个星号(*)表示它是一个生成器。只要是可以定义函数的地方,就可以定义生成器。
生成器作为默认迭代器:
一个实现 Iterator 接口的对象一定有 next()方法,还有一个可选的 return()方法用于提前终止迭代器。生成器对象除了有这两个方法,还有第三个方法:throw()。
此时生成器处于closed状态
如果在生成器函数内处理了错误,生成器就不会关闭
小结: ES6引入两个新的语言特性:迭代器和生成器。
迭代器是一个可以由任意对象实现的接口,支持连续获取对象产出的每一个值。(Symbol.iterator 属性)
生成器是一种特殊的函数,调用之后会返回一个生成器对象。(function*、yield)