> For the complete documentation index, see [llms.txt](https://lochiwei.gitbook.io/web/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lochiwei.gitbook.io/web/js/iteration/generator/func/yield-star-expr.md).

# yield\*

the "done" value of the iterator

[JS](/web/js.md) ⟩ [objects](/web/js/val/obj.md) ⟩ [built-in](/web/js/val/builtin.md) ⟩ [Generator](/web/js/iteration/generator.md) ⟩ [generator function](/web/js/iteration/generator/func.md) ⟩ yield\* expression

{% hint style="success" %}
the [value](/web/js/val.md) of <mark style="color:purple;">**yield\***</mark> [expression](/web/js/grammar/statement/expr.md) is the "<mark style="color:yellow;">**done**</mark>" value of the [iterator](/web/js/iteration/iterator.md).\
(<mark style="color:blue;">**undefined**</mark> by default)
{% endhint %}

{% tabs %}
{% tab title="💈範例" %}

* replit：[value of yield\* expression](https://replit.com/@pegasusroe/value-of-yield-expression#index.js)

```javascript
const { log } = console;

// generator: a()
function* a() {
    yield* [1, 2, 3];
    return 'foo';                // ⭐️ "done" value of `a`
}

// generator: b()
function* b() {
    
    // --------------------------------------------------------------
    const value = yield* a();    // ⭐️ "done" value of `a` returned
                                 //     after it's finished yielding.
    // --------------------------------------------------------------
    
    console.log(value)           // console: 'foo'
    
    return value + value;        // ⭐️ "done" value of `b`
}

// (iterable) iterators
const it1 = a();

log(it1.next());    // {value: 1, done: false}
log(it1.next());    // {value: 2, done: false}
log(it1.next());    // {value: 3, done: false}
log(it1.next());    // {value: 'foo'⭐️, done: true}

log(it1.next());    // {value: undefined❗, done: true}
                    // ⭐️ "done" value is only used once❗

const it2 = b();

log(it2.next());    // {value: 1, done: false}
log(it2.next());    // {value: 2, done: false}
log(it2.next());    // {value: 3, done: false}

log(it2.next());    // console: 'foo' <--- ⭐️ "done" value of `a` returned here
                    // {value: 'foofoo'⭐️, done: true}
```

{% endtab %}

{% tab title="⭐️ 重點" %}
{% hint style="warning" %} <mark style="color:purple;">**yield\***</mark> is an [expression](/web/js/grammar/statement/expr.md) (<mark style="color:red;">**not**</mark> a [statement](/web/js/grammar/statement.md)) that evaluates to a [value](/web/js/val.md).
{% endhint %}
{% 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*) [operator](/web/js/grammar/op.md) can <mark style="color:red;">**only**</mark> be used <mark style="color:yellow;">**within**</mark> [generator function](/web/js/iteration/generator/func.md)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="📘 手冊" %}

* [ ] [yield\*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield*) ⟩
  * [ ] [value of yield\* expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield*#the_value_of_yield_expression_itself)
    {% endtab %}
    {% endtabs %}
