# generator function

[JS](../..) ⟩ [iteration](..) ⟩ generator function

{% hint style="success" %}
defined by <mark style="color:blue;">**function\***</mark> keyword and returns a [](<> "mention") object.
{% endhint %}

{% tabs %}
{% tab title="🔴 主題" %}
* <mark style="color:yellow;">**syntax**</mark>
  * [func-star](func/func-star "mention")
  * [yield](func/yield "mention")
  * [yield-star-expr](func/yield-star-expr "mention")
* <mark style="color:yellow;">**use cases**</mark>
  * [as](func/as "mention") (variable, method)
  * as [make-iterator-method](../iterable/make-iterator-method "mention") of an [iterable](../iterable "mention").
* <mark style="color:yellow;">**examples**</mark>
  * [list](examples/list "mention") - sequence of numbers
  * [closedrange](examples/closedrange "mention")
  * [integers](examples/integers "mention")
  * [fibonacci](examples/fibonacci "mention")
* <mark style="color:yellow;">**composition of generator functions**</mark>
  * [zip](examples/zip "mention")
  * [seq](examples/seq "mention")
  * [interleave](examples/interleave "mention")
{% endtab %}

{% tab title="🧨 雷區" %}
{% hint style="danger" %}
<mark style="color:blue;">yield</mark> and [yield\*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield*) [op](../../grammar/op "mention") can <mark style="color:red;">**only**</mark> be used <mark style="color:yellow;">**within**</mark> [func](func "mention")s❗️
{% endhint %}

* replit：[yield must be in generator functions](https://replit.com/@pegasusroe/yield-must-in-generator-function#index.js)

```javascript
// this seems like a generator function, but there's a catch ...
function* sequence(...iterables) {

    // --------------------------------------------------------------
    // ⭐ `yield/yield*` only available within generator functions❗
    // --------------------------------------------------------------
    
    // ❌ but this `yield*` is within an "arrow function"❗
    //
    //                 ╭─── 🔸 arrow function ───╮
    iterables.forEach( iterable => yield* iterable );
    //                             ^^^^^^
    // ⛔ ReferenceError: yield is not defined 
    
}
```
{% endtab %}

{% tab title="⭐️ 重點" %}
{% hint style="danger" %}
<mark style="color:blue;">yield</mark> and [yield\*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield*) [op](../../grammar/op "mention") can <mark style="color:red;">**only**</mark> be used <mark style="color:yellow;">**within**</mark> [func](func "mention")s❗️
{% endhint %}

{% hint style="success" %}
we can use **generator functions** to make [iterable](../iterable "mention")s.
{% endhint %}

{% hint style="info" %}
<mark style="color:blue;">**yield\***</mark> <mark style="color:yellow;">**keyword**</mark> iterates an [iterable](../iterable "mention") and yields each of the resulting values.
{% endhint %}

{% hint style="danger" %}
there is <mark style="color:red;">**no way**</mark> to write a <mark style="color:purple;">**generator function**</mark> using [arrow](../../val/func/arrow "mention") syntax.
{% endhint %}
{% endtab %}

{% tab title="💈範例" %}
:floppy\_disk: replit：[generator functions & objects](https://replit.com/@pegasusroe/generator-functions-and-objects#generatorFunctions.js)

```javascript
// ⭐️ generator function
function* abc() {
  yield 'a';
  yield 'b';
  yield 'c';
}

// main
let str = '';

// ⭐️ for-of loop  ╭───╮ ----> ⭐️ generator object
for (const char of abc()) {
  str += char;
}                  // str = 'abc'
```
{% endtab %}

{% tab title="👥 相關" %}
* objects **returned** by **generator functions** are [iterable](../iterator/iterable "mention")s.
*
{% endtab %}

{% tab title="📘 手冊" %}
* [function\*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*) (declaration) ⭐️
{% endtab %}
{% endtabs %}
