ES7 中 Iterable、Iterator、Generator 详解

阅读时长 5 分钟读完

在 JavaScript 中,集合是一种重要的数据类型。ES7 提出了 Iterable、Iterator、Generator 三个新概念,使得集合变得更加容易操作和管理。在本文中,我们将详细探讨它们的定义、用法以及各自之间的关系。

Iterable

Iterable 原意是“可迭代的”,它是一种可以被迭代的对象,也就是说可以通过 for...of 循环进行遍历。具体来说,Iterable 对象必须实现一个名为 @@iterator 的方法,并且返回一个 Iterator 对象。例如:

-- -------------------- ---- -------
----- --- - -
  ------------------- -
    --- - - --
    ------ -
      ------ -
        ------ - ------ ---- ----- - - - --
      -
    --
  -
--

--- ------ ---- -- ---- -
  ------------------
-

上述代码中,我们定义了一个 obj 对象,同时实现了 @@iterator 方法并返回了一个包含 next 方法的对象。for...of 循环通过 obj 对象的 @@iterator 方法得到了 Iterator 对象,有了 Iterator 对象,后续的遍历就可以依靠 next 方法来完成。

需要注意的是,如果一个对象不是 Iterable,那么它就无法使用 for...of 循环来遍历。

Iterator

Iterator 原意是“迭代器”,它是一个带有 next 方法的对象,next 方法用来返回当前迭代位置的数据。具体来说,next 方法返回一个包含 value 和 done 两个属性的对象,value 属性表示当前迭代位置的数据,done 属性表示是否迭代完成。

Iterator 对象由 Iterable 对象生成,例如前文中的 obj 对象。Iterator 对象可以通过调用自己的 next 方法来进行遍历。一旦迭代完成,next 方法就会返回 { done: true },因此可以利用这个特性来写一个通用的迭代器函数实现:

-- -------------------- ---- -------
-------- --------------------- -
  --- - - --
  ------ -
    ------ -
      ------ - - ------------ - - ------ ----------- ----- ----- - - - ----- ---- --
    -
  --
-

----- ---- - ------------------ -- -- -- ----
--- ------ - ------------
----- -------------- -
  --------------------------
  ------ - ------------
-

Generator

Generator 原意是“生成器”,它是 ES6 中新增的一种函数类型。Generator 函数是一个状态机,内部可以定义多个 yield 表达式,yield 表达式定义了内部状态的输出值。例如:

-- -------------------- ---- -------
--------- ----- -
  ---------------- ----
  ----- --
  ---------------- ----
  ----- --
  ---------------- ----
-

----- ---- - ------
-------------------------------
-------------------------------
-------------------------------

上述代码中,我们定义了一个 Generator 函数 foo,它内部定义了三个 yield 表达式。每次调用 next 方法,Generator 函数就会运行到下一个 yield 表达式并暂停,返回一个包含 value 和 done 两个属性的对象。调用 next 方法时,可以向 Generator 函数传递一个值,这个值会成为 yield 的返回值。例如:

-- -------------------- ---- -------
--------- ----- -
  ---------------- ----
  ----- - - ----- --
  ---------------- --- ---
  ----- - - ----- --
  ---------------- --- ---
-

----- ---- - ------
-------------------------------
------------------------------------
------------------------------------

上述代码中,第一个 next 方法不需要传递参数,因为第一个 yield 表达式不会接收到任何值。第二个 next 方法传递了一个 "bar" 参数,这个参数会赋值给 const a。第三个 next 方法传递了一个 "baz" 参数,这个参数会赋值给 const b。

需要注意的是,当 Generator 函数的代码运行完毕之后,再次调用 next 方法将会执行完毕但不会返回任何数据。因此可以利用这个特性来定义一个无限循环的 Generator 函数:

-- -------------------- ---- -------
--------- ----- -
  --- - - --
  ----- ------ -
    ----- ----
  -
-

----- ---- - ------
-------------------------------
-------------------------------
-------------------------------

上述代码中,我们定义了一个无限循环的 Generator 函数 foo,每次返回自增的 i 属性。

总结

Iterable、Iterator、Generator 分别是可迭代的对象、迭代器对象、生成器函数。它们可以使得集合的操作更加容易和灵活。需要注意的是,Generator 函数需要运行才能返回数据,因此需要配合 Iterable 和 Iterator 对象来使用。在实际开发中,我们可以充分利用这些对象的特性,来简化和优化代码。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6480831848841e9894ff4199

纠错
反馈