# for-of vs. forEach

[JS](../../../../..)⟩ [syntax](broken-reference) ⟩ [for loops](..) ⟩ [for-of]() ⟩ vs. forEach

{% hint style="success" %}
<mark style="color:red;">**always**</mark>**&#x20;**<mark style="color:yellow;">**use**</mark> [**`for-of`**]() in ES6.

* It works on any [iterable](https://stackoverflow.com/a/41559281/1048572)
* It supports all kinds of control flow in the loop body, like `continue`, `break`, `return`, `yield` and `await`.

👉 [stackoverflow](https://stackoverflow.com/a/50844413/5409815)
{% endhint %}

{% tabs %}
{% tab title="⭐️ 重點" %}
{% hint style="danger" %}
<mark style="color:red;">**Don't use**</mark> <mark style="color:blue;">`forEach`</mark>**.** (In fact, never use `forEach` anywhere in ES6).

👉 [stackoverflow](https://stackoverflow.com/a/41559281/5409815)
{% endhint %}

{% hint style="warning" %}
<mark style="color:blue;">`forEach`</mark> has known pitfalls that make it unsuitable in some situations that can be properly handled with <mark style="color:blue;">`for`</mark> or <mark style="color:blue;">`for-of`</mark>:

* callback function creates new context (can be addressed with arrow function)
* doesn't support iterators
* doesn't support generator <mark style="color:blue;">`yield`</mark> and <mark style="color:blue;">`async..await`</mark>
* doesn't provide a proper way to terminate a loop early with <mark style="color:blue;">`break`</mark>

👉 [stackoverflow](https://stackoverflow.com/a/49424599/5409815)
{% endhint %}
{% endtab %}

{% tab title="🔴 主題" %}
* [iterate](../../../../../val/builtin/arr/iterate "mention")
{% endtab %}

{% tab title="👥 相關" %}
* "<mark style="color:yellow;">**holes**</mark>" in [**sparse arrays**](../../../../../val/builtin/arr/sparse) are <mark style="color:yellow;">**treated**</mark>**&#x20;**<mark style="color:red;">**differently**</mark> in [**for-of**]() and [**forEach**](../foreach).
  * for-of："<mark style="color:yellow;">**holes**</mark>" are treated as [**undefined**](../../../../../val/prim/undefined).
  * forEach："<mark style="color:yellow;">**holes**</mark>" are <mark style="color:red;">**ignored**</mark>.
{% endtab %}

{% tab title="💈範例" %}
```javascript
let a = [];        // sparse array
a[1] = 'hi';
a[5] = 'world';

let forofCount = 0;
let foreachCount = 0;

// ⭐️ for-of: treats "holes" as `undefined`.
for (const value of a) {
    forofCount += 1;
    console.log(forofCount, value);
}
// 1 undefined, 2 'hi', 3 undefined, ... 6 'world'

// ⭐️ forEach: ignores "holes".
a.forEach(value => {
    foreachCount += 1;
    console.log(foreachCount, value);
})
// 1 'hi', 2 'world'
```
{% endtab %}

{% tab title="🗣 討論" %}
* [Why should forEach be preferred over regular iterators?](https://stackoverflow.com/a/49424599/5409815)
* [Should one use for-of or forEach when iterating through an array?](https://stackoverflow.com/a/50844413/5409815)&#x20;
{% endtab %}
{% endtabs %}
