迭代器iterator;生成器generator;yield;yield *;
疑问:
generator是ES6出的,但ES5没有迭代器么?数组的遍历什么的怎么实现呢?
可迭代对象:可理解成数组或是集合
- 迭代器(iterator)
- 按需创建的一次性对象
- 每个迭代器都会关联一个可迭代对象
- 使用next()方法在可迭代对象中遍历数据
看起来迭代器的应用场景是和生成器generator绑定的,但其实这是所有可迭代对象通用的:
接收可迭代对象的原生语言特性包括: ❑ for-of循环 ❑ 数组解构 ❑ 扩展操作符 ❑ Array.from() ❑ 创建集合 ❑ 创建映射 ❑ Promise.all()接收由期约组成的可迭代对象 ❑ Promise.race()接收由期约组成的可迭代对象 ❑ yield*操作符,在生成器中使用
-
提前终止迭代器
可能的情况包括:
- for-of循环通过break、continue、return或throw提前退出;
- 解构操作并未消费所有值。
-
2 生成器
特性
- ES6新增。
- 可以在函数块内暂停和恢复代码执行。
- 生成器的形式是一个函数,函数名称前面加一个星号(*)表示它是一个生成器。
- 箭头函数不能用来定义生成器函数。
- 可实现自定义迭代器、实现协程。
- 与《你不知道的javascript》(中卷)存在差异:
- 红宝书:生成器创建生成器对象,生成器对象类似迭代器,实现了Iterator接口。
- you don’t know js:生成器创建迭代器对象。
- 我的见解:红宝书的写法更易懂,you don’t know js有点逻辑跳脱,容易混淆。
-
yield
yield关键字可以让生成器停止和开始执行
- 遇到这个关键字后,执行会停止,函数作用域的状态会被保留。
- 停止执行的生成器函数只能通过在生成器对象上调用next()方法来恢复执行
- yield关键字必须直接位于生成器函数定义中,出现在嵌套的非生成器函数中会抛出语法错误
- 放在数组的迭代方法里也会出错
- yield可实现输入和输出
将生成器对象当成可迭代对象
可以使用星号增强yield的行为,让它能够迭代一个可迭代对象
最有用的地方是实现递归操作,此时生成器可以产生自身
return()和throw()方法都可以用于强制生成器进入关闭状态。
- 只要通过return()进入关闭状态,就无法恢复了。
- 通过throw()方法,若错误在生成器内部未处理,则会进入关闭状态。
- 如果生成器对象还没有开始执行,那么调用throw()抛出的错误不会在函数内部被捕获,因为这相当于在函数块外部抛出了错误。