# for-of with strings

[JS](../../../../..)⟩ [syntax](broken-reference) ⟩ [for loops](..) ⟩ [for-of]() ⟩ with strings

{% hint style="success" %}
[str](../../../../../val/prim/str "mention")(s) are [iterable](../../../../../iteration/iterable "mention").

```javascript
let freq = {}; 

for(let char of "mississippi") { 
    freq[char] = (freq ?. [char] ?? 0) + 1;
}

freq    // { m: 1, i: 4, s: 4, p: 2 }
```
{% endhint %}

{% tabs %}
{% tab title="👥" %}
* [iterable](../../../../../iteration/iterable "mention")
* [with-object](with-object "mention")
* [in](../in "mention")
* [arr.entries](../../../../../val/builtin/arr/method/arr.entries "mention")
* <mark style="color:yellow;">**related concepts used in examples**</mark>
  * [optional-chaining](../../../../../val/obj/prop/access/optional-chaining "mention")
  * [nullish-coalescing](../../../../op/logical/nullish-coalescing "mention")
{% endtab %}

{% tab title="💈範例" %}
* replit： [for-of with strings](https://replit.com/@pegasusroe/for-of-with-strings-1#index.js)

{% hint style="warning" %}
<mark style="color:red;">**Note**</mark>：in the following code, '❤' is actually '❤️', except line 40, 46:exclamation:
{% endhint %}

{% code lineNumbers="true" %}
```javascript
// ⭐ string with emojis.
const str = 'I ❤️ 🐣';

let count = 0;    // count "characters" with for-of loop.
let a = [];       // store "characters" in an array.
let i = 0;        // array element index.

// ⭐ collect "letters" using for-of
for (a[i++] of str) {          // ⭐ `lvalue` can be used in for-of.
    count += 1;
}

// ⭐ collect "letters" using `str.length`
let b = [];

for (let i = 0; i < 7; i++) {
    b[i] = str[i];
}

// ⭐ code points           // '❤️' has two code points❗
'❤️'.codePointAt(0),         //  10084
'❤️'.codePointAt(1),         //  65039

'🐣'.codePointAt(0),        // 128035

// ⭐ string length is expected to be 5❗
//    neither `.length` nor `for-of` is correnct❗
str.length,                 // 7❗
count,                      // 6❗

// (str.length) 7 elements❗
b.map(c => c.codePointAt(0)), 
// [73, 32, 10084, 65039, 32, 55357, 56355]
//          ╰─── ❤️ ───╯       ╰─── 🐣 ───╯
//                                  └── surrogate pair ?

// (for-of) 6 elements❗
a,                          
// [ 'I', ' ', '❤', '️', ' ', '🐣' ]    
//             ╰──❤️──╯
a.map(c => c.codePointAt(0)),
// [ 73, 32, 10084, 65039, 32, 128035 ]
//           ╰─── ❤️ ───╯       ╰─🐣─╯

String.fromCodePoint(10084), // '❤'
```
{% endcode %}
{% endtab %}

{% tab title="📗" %}
* [ ] [javascript-the-definitive-guide](../../../../../../master/ref/javascript-the-definitive-guide "mention") ⟩ 5.4.4 for/of loop
* [ ] Unicode Table ⟩ [U+FE0F (65039)](https://unicode-table.com/en/FE0F/)
{% endtab %}

{% tab title="📘" %}
* [ ] [for...of](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of)
* [ ] [Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) ⟩
  * [Object.keys()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys)
  * [Object.values()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values)
  * [Object.entries()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries)
* [ ] Object.prototype ⟩
  * [.hasOwnProperty()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty)
* [ ] &#x20;["in" operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in)
{% endtab %}

{% tab title="🗣 討論" %}
* [How to get the Unicode code point for a character in Javascript?](https://stackoverflow.com/questions/48009201/how-to-get-the-unicode-code-point-for-a-character-in-javascript)
* [Why '❌'\[0\] === '❌' but '✔️'\[0\] !== '✔️'?](https://stackoverflow.com/questions/69548147/why-0-but-%EF%B8%8F0-%EF%B8%8F)
{% endtab %}
{% endtabs %}
