编辑
2020-04-03
前端开发
00

目录

所有的新概念并不是人们闲的没事想出来的,而是为了解决已有的某些问题才出现的。所以只要我们从历史的角度去看,就能更容易理解这些新概念!

什么是迭代器

我们在用循环语句迭代数据时,必须要初始化一个变量来记录每次迭代在数据集中的位置,比如说for循环:

js
const arr = ['red', 'green', 'blue'] for (let index = 0; index < arr.length; index++) { console.log(i) }

在上面的代码中,我们就是通过变量i来跟踪索引,我们通过观察i来了解现在循环到数组中的第几个项了。

这个例子中的循环很简单,但是如果嵌套循环,则需要追踪多个变量,代码复杂度增加,就很容易出错。就像Promise的出现是为了解决回调地域一样,迭代器的出现就是为了消除这种复杂性并减少循环的错误。

为了更好的理解迭代器的运行方式,我们先用 ES5 的语法写一个迭代器函数,代码如下:

js
function createIterator(items) { var i = 0 return { next: function() { var done = i >= items.length var value = !done ? items[i++] : undefined return { done, value } } } } var iterator = createIterator([1, 2, 3]) console.log(iterator.next()) // {value:1, done:false} console.log(iterator.next()) // {value:2, done:false} console.log(iterator.next()) // {value:3, done:false} console.log(iterator.next()) // {value:undefined, done:true}

其实这段代码已经给出了迭代器的定义:迭代器函数定义了一个next()方法,这个方法执行后会返回一个对象,拥有valuedone两个属性,value告诉你下次执行时候的返回值,done告诉你是否执行完了。

什么是生成器

生成器就是“能够返回一个迭代器函数的函数”。

上面的迭代器我们是自己定义的,比较麻烦,所以官方出了一个可以生成迭代器的函数,试着比较一下下面两段效果一样的代码:

js
// 自定义迭代器 function createIterator(items) { var i = 0 return { next: function() { var done = i >= items.length var value = !done ? items[i++] : undefined return { done, value } } } } // 使用生成器函数返回迭代器 function* createIterator(items) { for (let i = 0; i < items.length; i++) { yield items[i] } }

就是这么简洁好用!

还是上面那个例子,我们粘过来,不过这一次我们使用生成器函数:

js
function* createIterator(items) { for (let i = 0; i < items.length; i++) { yield items[i] } } let iterator = createIterator([1, 2, 3]) console.log(iterator.next()) // { value:1, done: false } console.log(iterator.next()) // { value:2, done: false } console.log(iterator.next()) // { value:3, done: false } console.log(iterator.next()) // { value:undefined, done: true }

其中,function*用来声明一个生成器,yield是一个关键字。

yield是啥?在调用迭代器的next()方法时,遇到yield就会暂停,然后返回迭代器的结果对象{ value: xx, done: xx }。当我们再次调用生成器的next()方法时,如果它还没执行到头(done 不为 true),那么他就会继续执行。

以上。

本文作者:青波

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!