迭代器与生成器


迭代器

迭代器(iterator),是确使用户可在容器对象(container,例如链表或数组)上遍访的对象,使用该接口无需关心对象的内部实现细节。

从迭代器的定义我们可以看出来,迭代器是帮助我们对某个数据结构进行遍历的对象。

  • 在JavaScript中,迭代器也是一个具体的对象,这个对象需要符合迭代器协议(iterator protocol):

  • 迭代器协议定义了产生一系列值(无论是有限还是无限个)的标准方式;

  • 那么在js中这个标准就是一个特定的next方法

  • next方法有如下的要求:

  • 一个无参数或者一个参数的函数,返回一个应当拥有以下两个属性的对象:

  • done(boolean)

    • 如果迭代器可以产生序列中的下一个值,则为 false。(这等价于没有指定 done 这个属性。)
    • 如果迭代器已将序列迭代完毕,则为 true。这种情况下,value 是可选的,如果它依然存在,即为迭代结束之后的默认返回值。
  • value

    • 迭代器返回的任何 JavaScript 值。done 为 true 时可省略。

迭代器实现:

image-20220425163600080

可迭代对象

  • 什么又是可迭代对象呢?
    • 它和迭代器是不同的概念;
    • 当一个对象实现了iterable protocol协议时,它就是一个可迭代对象;
    • 这个对象的要求是必须实现 @@iterator 方法,在代码中我们使用 Symbol.iterator 访问该属性;
  • 当我们要问一个问题,我们转成这样的一个东西有什么好处呢?
  • 当一个对象变成一个可迭代对象的时候,进行某些迭代操作,比如 for…of 操作时,其实就会调用它的@@iterator 方法;

image-20220429161731851

生成器

什么是生成器?

  • 生成器是ES6中新增的一种函数控制、使用的方案,它可以让我们更加灵活的控制函数什么时候继续执行、暂停执行等。

  • 平时我们会编写很多的函数,这些函数终止的条件通常是返回值或者发生了异常。

  • 生成器函数也是一个函数,但是和普通的函数有一些区别:

  • 首先,生成器函数需要在function的后面加一个符号:*****

  • 其次,生成器函数可以通过yield关键字来控制函数的执行流程:

  • 最后,生成器函数的返回值是一个Generator(生成器):

    • 生成器事实上是一种特殊的迭代器
    • MDN:Instead, they return a special type of iterator, called a Generator.
  • 我们发现上面的生成器函数foo的执行体压根没有执行,它只是返回了一个生成器对象。

    • 那么我们如何可以让它执行函数中的东西呢?调用next即可;
    • 我们之前学习迭代器时,知道迭代器的next是会有返回值的;
    • 但是我们很多时候不希望next返回的是一个undefined,这个时候我们可以通过yield来返回结果

image-20220429165648505

  • 函数既然可以暂停来分段执行,那么函数应该是可以传递参数的,我们是否可以给每个分段来传递参数呢?
    • 答案是可以的;
    • 我们在调用next函数的时候,可以给它传递参数,那么这个参数会作为上一个yield语句的返回值;
    • 注意:也就是说我们是为本次的函数代码块执行提供了一个值;

image-20220429170221638

生成器代替迭代器

image-20220429171616724


文章作者: Yuukyou
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Yuukyou !
评论
  目录