# iterable

[JS](https://lochiwei.gitbook.io/web/js) ⟩ [iteration](https://lochiwei.gitbook.io/web/js/iteration) ⟩ iterable

{% hint style="success" %}
[es6](https://lochiwei.gitbook.io/web/js/feature/es6 "mention")  &#x20;

an object that <mark style="color:yellow;">**can**</mark> [**make iterators**](https://lochiwei.gitbook.io/web/js/iteration/iterable/make-iterator-method). (like [Sequence](https://developer.apple.com/documentation/swift/sequence) in Swift, must implement <mark style="color:blue;">.makeIterator()</mark> method)

```javascript
for (const value of iterable) { ... }    // for-of
[...iterable]                 // spread into array elements
f(...iterable)                // spread into function arguments
const [a, b, c] = iterable;   // destructuring iterable
Array.from(iterable)          // iterable -> array
```

{% endhint %}

{% tabs %}
{% tab title="🧨" %}
{% hint style="warning" %}
(by default) [obj](https://lochiwei.gitbook.io/web/js/val/obj "mention") <mark style="color:yellow;">**is**</mark>**&#x20;**<mark style="color:red;">**not**</mark> <mark style="color:purple;">**iterable**</mark>:exclamation:

```javascript
let obj = { x: 1, y: 2, z: 3 };
for (let value of obj) { }                   // ⛔ TypeError

// ⭐️ workarounds
for (let key of Object.keys(obj) { ... }
for (let key in obj) { ... }                 // for-in
for (let value of Object.values(obj) { ... }
for (let [key, value] of Object.entries(obj) { ... }
```

:point\_right: [for-in-vs.-for-of-vs.-in](https://lochiwei.gitbook.io/web/js/grammar/statement/loop/for/for-in-vs.-for-of-vs.-in "mention")
{% endhint %}

{% hint style="warning" %}
[live-array](https://lochiwei.gitbook.io/web/js/grammar/statement/loop/for/of/live-array "mention")
{% endhint %}
{% endtab %}

{% tab title="⭐️" %}
{% hint style="success" %} <mark style="color:yellow;">**use cases：**</mark>

```javascript
for (const item of iterable) { ... } // ⭐️ for-of loop
[...iterable]                        // ⭐️ spread into array elements
f(...iterable)                       // ⭐️ spread into function arguments
let [a, b, c] = iterable             // ⭐️ iterable destructuring

// ⭐️ functios that accept iterables:
Array.from(iterable/array-like)
Promise.all(iterable)
```

{% endhint %}

{% hint style="success" %} <mark style="color:yellow;">**iterables**</mark>：

* [arr](https://lochiwei.gitbook.io/web/js/val/builtin/arr "mention"), [str](https://lochiwei.gitbook.io/web/js/val/prim/str "mention"), [set](https://lochiwei.gitbook.io/web/js/val/builtin/set "mention"), [map](https://lochiwei.gitbook.io/web/js/val/builtin/map "mention"), [TypedArray](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray),&#x20;
* [Broken link](https://lochiwei.gitbook.io/web/js/iteration/broken-reference "mention") objects returned by [func](https://lochiwei.gitbook.io/web/js/iteration/generator/func "mention")s.
* [custom](https://lochiwei.gitbook.io/web/js/iteration/iterable/custom "mention")
* [NodeList](https://developer.mozilla.org/en-US/docs/Web/API/NodeList), [arguments](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments) object, ...
* array.[keys()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/keys), map.[entries()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries), ...
* [str.matchall](https://lochiwei.gitbook.io/web/js/val/prim/str/method/str.matchall "mention")
  {% endhint %}

{% hint style="danger" %}
must implement the [make-iterator-method](https://lochiwei.gitbook.io/web/js/iteration/iterable/make-iterator-method "mention") named \[[Symbol.iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator)].
{% endhint %}

{% hint style="danger" %}
some <mark style="color:yellow;">**iterables**</mark> [only iterate once](https://lochiwei.gitbook.io/web/js/iteration/iterable/only-iterate-once)❗️
{% endhint %}

{% hint style="info" %}
an <mark style="color:purple;">**iterable**</mark> can be <mark style="color:yellow;">**infinite**</mark>. ( 👉 see： [integers](https://lochiwei.gitbook.io/web/js/iteration/generator/examples/integers "mention"))
{% endhint %}
{% endtab %}

{% tab title="🔴" %}

* <mark style="color:yellow;">**comforming to Iterable**</mark>
  * [make-iterator-method](https://lochiwei.gitbook.io/web/js/iteration/iterable/make-iterator-method "mention") - method named `[Symbol.iterator]`.
  * [iterable+ext](https://lochiwei.gitbook.io/web/js/iteration/iterable+ext "mention") (extension) - extends iterables with custom methods.
  * [isiterable](https://lochiwei.gitbook.io/web/js/iteration/iterable+ext/isiterable "mention") - check if an object is iterable.
* <mark style="color:yellow;">**iterable types**</mark>
  * [str](https://lochiwei.gitbook.io/web/js/val/prim/str "mention") <mark style="color:yellow;">**/**</mark> [arr](https://lochiwei.gitbook.io/web/js/val/builtin/arr "mention") <mark style="color:yellow;">**/**</mark> [set](https://lochiwei.gitbook.io/web/js/val/builtin/set "mention") <mark style="color:yellow;">**/**</mark> [map](https://lochiwei.gitbook.io/web/js/val/builtin/map "mention")
* :floppy\_disk: <mark style="color:yellow;">**use cases**</mark>
  * `for (const value of`` `<mark style="color:purple;">`iterable`</mark>`)` - [of](https://lochiwei.gitbook.io/web/js/grammar/statement/loop/for/of "mention") loop.
  * `[...`<mark style="color:purple;">`iterable`</mark>`]` - [spread](https://lochiwei.gitbook.io/web/js/grammar/op/spread) into array elements.
  * `f(...`<mark style="color:purple;">`iterable`</mark>`)` - [spread](https://lochiwei.gitbook.io/web/js/grammar/op/spread) into function arguments.
  * `const [a, b, c] =`` `<mark style="color:purple;">`iterable`</mark>`;` - iterable [destructuring](https://lochiwei.gitbook.io/web/js/grammar/op/assign/destruct).
  * `Array.from(`<mark style="color:purple;">`iterable`</mark>`)` - convert to array.
* <mark style="color:yellow;">**special iterable**</mark>
  * [only-iterate-once](https://lochiwei.gitbook.io/web/js/iteration/iterable/only-iterate-once "mention")
* <mark style="color:yellow;">**defining iterables**</mark>
  * [make-iterables](https://lochiwei.gitbook.io/web/js/iteration/iterable/make-iterables "mention")
  * [make-iterable](https://lochiwei.gitbook.io/web/js/iteration/iterator/make-iterable "mention")
  * [using class (with private properties)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#defining_an_iterable_with_a_class)
* :sparkles: [<mark style="color:yellow;">**examples**</mark>](https://lochiwei.gitbook.io/web/js/iteration/iterable/custom)：
  * [range](https://lochiwei.gitbook.io/web/js/iteration/iterable+ext/range "mention") - half-open range of numbers.
  * [integers](https://lochiwei.gitbook.io/web/js/iteration/generator/examples/integers "mention") - generate <mark style="color:yellow;">**infinite**</mark> iterable.
  * [closedrange](https://lochiwei.gitbook.io/web/js/iteration/iterable/custom/closedrange "mention") - closed range of integers.
  * [integers](https://lochiwei.gitbook.io/web/js/iteration/generator/examples/integers "mention")
    {% endtab %}

{% tab title="👥" %}

* [for](https://lochiwei.gitbook.io/web/js/grammar/statement/loop/for "mention")
* [arr](https://lochiwei.gitbook.io/web/js/val/builtin/arr "mention")
* [array-like](https://lochiwei.gitbook.io/web/js/val/builtin/arr/array-like "mention")s and [iterable](https://lochiwei.gitbook.io/web/js/iteration/iterable "mention")s are <mark style="color:yellow;">**different**</mark> things.
* &#x20;[destruct](https://lochiwei.gitbook.io/web/js/grammar/op/assign/destruct "mention") can be used with <mark style="color:yellow;">**iterables**</mark>.&#x20;
  {% endtab %}

{% tab title="🗺️" %} <img src="https://2527454625-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MfvEFZnSBhKT6fJmus0%2Fuploads%2FLDbsdTPR3ENAv8P81akq%2Fiteration-related-types.svg?alt=media&#x26;token=6c6da705-70d0-4fd6-97b8-5663b3d61f2d" alt="" class="gitbook-drawing">
{% endtab %}

{% tab title="💈" %}

* <mark style="color:yellow;">**defining iterable**</mark> (using [func](https://lochiwei.gitbook.io/web/js/iteration/generator/func "mention"))

```javascript
const iterable = {
    // ⭐️ "make-iterator" method
    *[Symbol.iterator]() {
        yield 1; yield 2; yield 3;
    },
};
```

<mark style="color:yellow;">**more examples ...**</mark>

* [integers](https://lochiwei.gitbook.io/web/js/iteration/generator/examples/integers "mention") - generate non-negative integers.
* [sequence](https://lochiwei.gitbook.io/web/js/iteration/iterable/custom/sequence "mention") - sequence of numbers.
  {% endtab %}

{% tab title="📗" %}

* [ ] ExploringJS ⟩ [21. Iterables and Iterators](https://exploringjs.com/es6/ch_iteration.html) ⭐️
* [ ] JS.info ⟩ [iterables](https://javascript.info/iterable)
* [ ] [javascript-the-definitive-guide](https://lochiwei.gitbook.io/web/master/ref/javascript-the-definitive-guide "mention") ⟩ Ch. 12
* [ ] 2ality ⟩ [JavaScript needs more helper functions for iteration (map, filter, etc.)](https://2ality.com/2021/08/iteration-helpers.html)
  {% endtab %}

{% tab title="📘" %}

* [for...of](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of)
* [Array.from()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from) - convert **iterable** / [array-like](https://lochiwei.gitbook.io/web/js/val/builtin/arr/array-like "mention") to **array**.
* [iterable protocol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterable_protocol) ( = Sequence protocol in Swift )
* [Symbol.iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator) ( = makeIterator in Swift )
* [Built-in APIs accepting iterables](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#built-in_apis_accepting_iterables)
* [Syntaxes expecting iterables](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#syntaxes_expecting_iterables)
  {% endtab %}

{% tab title="🗣" %}

* [What is the technical definition of a Javascript iterable and how do you test for it?](https://stackoverflow.com/a/41559281/5409815)
  {% endtab %}
  {% endtabs %}
