迭代器工厂:生成器

阅读 1.6k
标签: JavaScript

在上一篇《优雅的遍历:迭代器》中,已经知道了迭代器的用途,但没有说明如何获得迭代器,本篇就如何获得迭代器进行介绍。

什么是生成器

生成器就是一个返回迭代器的函数,它长这样:

javascript
function* generator() {
yield 3
yield 6
}
let iterator = generator()

它和普通函数很像,但也带有明显的个人特色,第一个特色是function关键字后面带有星号(*),第二个特色是函数体中有关键字yield。通过调用它就会获得一个迭代器。

对于生成器而言,其最特殊的地方在于每执行一条yield语句后,函数就会自动停止执行

比如,上面代码中,执行完语句yield 3之后,函数便不再执行其他语句,直到再次调用迭代器的next()方法才会继续执行yield 6语句。

默认的迭代器

在上一篇中,我们遇到了一个疑惑:就是用for-of迭代数组时,JavaScript引擎到底帮我们做了什么?其实是这样:

javascript
let arr = [100, 200, 300]
let iterator = arr[Symbol.iterator]()

通过Symbol.iterator获取了数组arr的默认迭代器。由于具有Symbol.iterator属性的对象都有默认的迭代器,因此可以用它来检测对象是否为可迭代对象:

javascript
function isIterable(object) {
return typeof object[Symbol.iterator] === "function"
}

上面的isIterable()函数可以检测指定对象中是否存在默认的迭代器,for-of在执行前也会做类似的检查。

创建可迭代对象

默认情况下,开发者创建的对象都是不可迭代对象,如果要将其变成可迭代的对象,需要给它添加一个Symbol.iterator属性,并且该属性是一个生成器:

javascript
let collection = {
items: [],
*[Symbol.iterator]() {
for (let item of this.items) {
yield item
}
}
}
collection.items.push(100)
collection.items.push('abc')
for (let col of collection) {
console.log(col)
}

上面代码中,给collection对象添加了一个Symbol.iterator属性(生成器),这样,collection就从不可迭代变成了可迭代。

参考

  • 深入理解ES6,Nicholas C. Zakas
最后编辑于: 2022-06-28

评论(0条)

(必填)
复制成功