盤點JavaScript中的Iterable object(可迭代對象)
大家好,我是進階學習者。
一、概念
可迭代(Iterable) 對象是數(shù)組的泛化。這個概念是說任何對象都可以被定制為可在 for..of 循環(huán)中使用的對象。
數(shù)組是可迭代的。但不僅僅是數(shù)組,很多其他內(nèi)建對象也都是可迭代的。
二、通過創(chuàng)建一個對象,就可以輕松地掌握可迭代的概念。
1.字符串是可迭代的
數(shù)組和字符串是使用最廣泛的內(nèi)建可迭代對象。
對于一個字符串,for..of 遍歷它的每個字符:
- for (let char of "test") {
- // 觸發(fā) 4 次,每個字符一次
- alert( char ); // t, then e, then s, then t
- }
對于代理對(surrogate pairs),它也能正常工作!
(譯注:這里的代理對也就指的是 UTF-16 的擴展字符)
- let str = '𝒳😂';
- for (let char of str) {
- alert( char ); // 𝒳,然后是 😂
- }
2. 顯式調用迭代器(如何顯式地使用迭代器?)。
將會采用與 for..of 完全相同的方式遍歷字符串,但使用的是直接調用。這段代碼創(chuàng)建了一個字符串迭代器,并“手動”從中獲取值。
- let str = "Hello"; // 和 for..of 做相同的事//
- for (let char of str)
- alert(char);
- let iterator = str[Symbol.iterator]();
- while (true) {
- let result = iterator.next();
- if (result.done) break;
- alert(result.value); // 一個接一個地輸出字符
- }
注:
很少需要這樣做,但是比 for..of 給了更多的控制權。例如,可以拆分迭代過程:迭代一部分,然后停止,做一些其他處理,然后再恢復迭代。
3. Array.from
有一個全局方法 Array.from 可以接受一個可迭代或類數(shù)組的值,并從中獲取一個“真正的”數(shù)組。然后就可以對其調用數(shù)組方法了。
例:
- let arrayLike = {
- 0: "Hello",
- 1: "World",
- length: 2
- };
- let arr = Array.from(arrayLike); // (*)
- alert(arr.pop()); // World(pop 方法有效)// World(pop 方法有效)
運行結果:
在 (*) 行的 Array.from 方法接受對象,檢查它是一個可迭代對象或類數(shù)組對象,然后創(chuàng)建一個新數(shù)組,并將該對象的所有元素復制到這個新數(shù)組。
現(xiàn)在用 Array.from 將一個字符串轉換為單個字符的數(shù)組:
- let str = '𝒳😂';// 將 str 拆分為字符數(shù)組
- let chars = Array.from(str);alert(chars[0]); // 𝒳
- alert(chars[1]); // 😂
- alert(chars.length); // 2
運行結果:
注:
與 str.split 方法不同,它依賴于字符串的可迭代特性。
因此,就像 for..of 一樣,可以正確地處理代理對(surrogate pair)。(譯注:代理對也就是 UTF-16 擴展字符。)
另外一種表達方式
技術上來說,它和下文做了同樣的事:
- let str = '𝒳😂';
- let chars = []; // Array.from 內(nèi)部執(zhí)行相同的循環(huán)
- for (let char of str) {
- chars.push(char);
- }
- alert(chars);
運行結果:
但 Array.from 精簡很多。
甚至可以基于 Array.from 創(chuàng)建代理感知(surrogate-aware)的slice 方法(譯注:也就是能夠處理 UTF-16 擴展字符的 slice 方法):
- function slice(str, start, end) {
- return Array.from(str).slice(start, end).join('');
- }
- let str = '𝒳😂𩷶';
- alert(slice(str, 1, 3)); // 😂𩷶// 原生方法不支持識別代理對(譯注:UTF-16 擴展字符)
- alert(str.slice(1, 3)); // 亂碼(兩個不同 UTF-16 擴展字符碎片拼接的結果)
三、總結
本文基于JavaScript基礎。介紹了Iterable object(可迭代對象),應用 for..of 的對象被稱為 可迭代的。通過創(chuàng)建一個對象,詳細的講解了字符串是可迭代的。顯式調用迭代器,以及在實際中 Array.from的應用。
歡迎大家積極嘗試,有時候看到別人實現(xiàn)起來很簡單,但是到自己動手實現(xiàn)的時候,總會有各種各樣的問題,切勿眼高手低,勤動手,才可以理解的更加深刻。
代碼很簡單,希望對你學習有幫助。