å¯è¿ä»£ï¼Iterableï¼ å¯¹è±¡æ¯æ°ç»çæ³åãè¿ä¸ªæ¦å¿µæ¯è¯´ä»»ä½å¯¹è±¡é½å¯ä»¥è¢«å®å¶ä¸ºå¯å¨ for..of 循ç¯ä¸ä½¿ç¨ç对象ã
æ°ç»æ¯å¯è¿ä»£çãä½ä¸ä» ä» æ¯æ°ç»ãå¾å¤å ¶ä»å 建对象ä¹é½æ¯å¯è¿ä»£çãä¾å¦åç¬¦ä¸²ä¹æ¯å¯è¿ä»£çã
妿ä»ä¸¥æ ¼æä¹ä¸è®²ï¼å¯¹è±¡ä¸æ¯æ°ç»ï¼èæ¯è¡¨ç¤ºæç©çéåï¼å表ï¼éåï¼ï¼for..of æ¯ä¸ä¸ªè½å¤éåå®çå¾å¥½çè¯æ³ï¼å æ¤ï¼è®©æä»¬æ¥ççå¦ä½ä½¿å
¶åæ¥ä½ç¨ã
Symbol.iterator
éè¿èªå·±å建ä¸ä¸ªå¯¹è±¡ï¼æä»¬å°±å¯ä»¥è½»æ¾å°ææ¡å¯è¿ä»£çæ¦å¿µã
ä¾å¦ï¼æä»¬æä¸ä¸ªå¯¹è±¡ï¼å®å¹¶ä¸æ¯æ°ç»ï¼ä½æ¯çä¸å»å¾éåä½¿ç¨ for..of 循ç¯ã
æ¯å¦ä¸ä¸ª range 对象ï¼å®ä»£è¡¨äºä¸ä¸ªæ°ååºé´ï¼
let range = {
from: 1,
to: 5
};
// æä»¬å¸æ for..of è¿æ ·è¿è¡ï¼
// for(let num of range) ... num=1,2,3,4,5
为äºè®© range 对象å¯è¿ä»£ï¼ä¹å°±è®© for..of å¯ä»¥è¿è¡ï¼æä»¬éè¦ä¸ºå¯¹è±¡æ·»å ä¸ä¸ªå为 Symbol.iterator çæ¹æ³ï¼ä¸ä¸ªä¸é¨ç¨äºä½¿å¯¹è±¡å¯è¿ä»£çå
建 symbolï¼ã
- å½
for..of循ç¯å¯å¨æ¶ï¼å®ä¼è°ç¨è¿ä¸ªæ¹æ³ï¼å¦ææ²¡æ¾å°ï¼å°±ä¼æ¥éï¼ãè¿ä¸ªæ¹æ³å¿ é¡»è¿åä¸ä¸ª è¿ä»£å¨ï¼iteratorï¼ ââ ä¸ä¸ªænextæ¹æ³ç对象ã - 仿¤å¼å§ï¼
for..ofä» éç¨äºè¿ä¸ªè¢«è¿åç对象ã - å½
for..of循ç¯å¸æåå¾ä¸ä¸ä¸ªæ°å¼ï¼å®å°±è°ç¨è¿ä¸ªå¯¹è±¡çnext()æ¹æ³ã next()æ¹æ³è¿åçç»æçæ ¼å¼å¿ é¡»æ¯{done: Boolean, value: any}ï¼å½done=trueæ¶ï¼è¡¨ç¤ºå¾ªç¯ç»æï¼å¦åvalueæ¯ä¸ä¸ä¸ªå¼ã
è¿æ¯å¸¦ææ³¨éç range ç宿´å®ç°ï¼
let range = {
from: 1,
to: 5
};
// 1. for..of è°ç¨é¦å
ä¼è°ç¨è¿ä¸ªï¼
range[Symbol.iterator] = function() {
// â¦â¦å®è¿åè¿ä»£å¨å¯¹è±¡ï¼iterator objectï¼ï¼
// 2. æ¥ä¸æ¥ï¼for..of ä»
ä¸ä¸é¢çè¿ä»£å¨å¯¹è±¡ä¸èµ·å·¥ä½ï¼è¦æ±å®æä¾ä¸ä¸ä¸ªå¼
return {
current: this.from,
last: this.to,
// 3. next() å¨ for..of çæ¯ä¸è½®å¾ªç¯è¿ä»£ä¸è¢«è°ç¨
next() {
// 4. å®å°ä¼è¿å {done:.., value :...} æ ¼å¼ç对象
if (this.current <= this.last) {
return { done: false, value: this.current++ };
} else {
return { done: true };
}
}
};
};
// ç°å¨å®å¯ä»¥è¿è¡äºï¼
for (let num of range) {
alert(num); // 1, ç¶åæ¯ 2, 3, 4, 5
}
请注æå¯è¿ä»£å¯¹è±¡çæ ¸å¿åè½ï¼å ³æ³¨ç¹å离ã
rangeèªèº«æ²¡ænext()æ¹æ³ã- ç¸åï¼æ¯éè¿è°ç¨
range[Symbol.iterator]()å建äºå¦ä¸ä¸ªå¯¹è±¡ï¼å³æè°çâè¿ä»£å¨â对象ï¼å¹¶ä¸å®çnextä¼ä¸ºè¿ä»£çæå¼ã
å æ¤ï¼è¿ä»£å¨å¯¹è±¡åä¸å ¶è¿è¡è¿ä»£ç对象æ¯åå¼çã
仿æ¯ä¸è¯´ï¼æä»¬å¯ä»¥å°å®ä»¬åå¹¶ï¼å¹¶ä½¿ç¨ range èªèº«ä½ä¸ºè¿ä»£å¨æ¥ç®å代ç ã
å°±åè¿æ ·ï¼
let range = {
from: 1,
to: 5,
[Symbol.iterator]() {
this.current = this.from;
return this;
},
next() {
if (this.current <= this.to) {
return { done: false, value: this.current++ };
} else {
return { done: true };
}
}
};
for (let num of range) {
alert(num); // 1, ç¶åæ¯ 2, 3, 4, 5
}
ç°å¨ range[Symbol.iterator]() è¿åçæ¯ range 对象èªèº«ï¼å®å
æ¬äºå¿
éç next() æ¹æ³ï¼å¹¶éè¿ this.current è®°å¿äºå½åçè¿ä»£è¿ç¨ãè¿æ ·æ´çï¼å¯¹åï¼æ¯çãææ¶è¿æ ·ä¹å¯ä»¥ã
ä½ç¼ºç¹æ¯ï¼ç°å¨ä¸å¯è½åæ¶å¨å¯¹è±¡ä¸è¿è¡ä¸¤ä¸ª for..of 循ç¯äºï¼å®ä»¬å°å
±äº«è¿ä»£ç¶æï¼å ä¸ºåªæä¸ä¸ªè¿ä»£å¨ï¼å³å¯¹è±¡æ¬èº«ã使¯ä¸¤ä¸ªå¹¶è¡ç for..of æ¯å¾ç½è§çï¼å³ä½¿å¨å¼æ¥æ
åµä¸ã
æ ç©·è¿ä»£å¨ä¹æ¯å¯è½çãä¾å¦ï¼å° range 设置为 range.to = Infinityï¼è¿æ¶ range åæä¸ºäºæ ç©·è¿ä»£å¨ãæè
æä»¬å¯ä»¥å建ä¸ä¸ªå¯è¿ä»£å¯¹è±¡ï¼å®çæä¸ä¸ªæ ç©·ä¼ªéæºæ°åºåã乿¯å¯è½çã
next 没æä»ä¹éå¶ï¼å®å¯ä»¥è¿åè¶æ¥è¶å¤çå¼ï¼è¿æ¯æ£å¸¸çã
å½ç¶ï¼è¿ä»£è¿ç§å¯¹è±¡ç for..of 循ç¯å°ä¸ä¼åæ¢ã使¯æä»¬å¯ä»¥éè¿ä½¿ç¨ break æ¥åæ¢å®ã
å符串æ¯å¯è¿ä»£ç
æ°ç»åå符串æ¯ä½¿ç¨æå¹¿æ³çå 建å¯è¿ä»£å¯¹è±¡ã
对äºä¸ä¸ªå符串ï¼for..of éåå®çæ¯ä¸ªå符ï¼
for (let char of "test") {
// 触å 4 æ¬¡ï¼æ¯ä¸ªåç¬¦ä¸æ¬¡
alert( char ); // t, then e, then s, then t
}
对äºä»£ç对ï¼surrogate pairsï¼ï¼å®ä¹è½æ£å¸¸å·¥ä½ï¼ï¼è¯æ³¨ï¼è¿éç代ç对ä¹å°±æçæ¯ UTF-16 çæ©å±å符ï¼
let str = 'ð³ð';
for (let char of str) {
alert( char ); // ð³ï¼ç¶åæ¯ ð
}
æ¾å¼è°ç¨è¿ä»£å¨
ä¸ºäºæ´æ·±å±å°äºè§£åºå±ç¥è¯ï¼è®©æä»¬æ¥ççå¦ä½æ¾å¼å°ä½¿ç¨è¿ä»£å¨ã
æä»¬å°ä¼éç¨ä¸ for..of å®å
¨ç¸åçæ¹å¼éåå符串ï¼ä½ä½¿ç¨çæ¯ç´æ¥è°ç¨ãè¿æ®µä»£ç å建äºä¸ä¸ªå符串è¿ä»£å¨ï¼å¹¶âæå¨âä»ä¸è·åå¼ã
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 ç»äºæä»¬æ´å¤çæ§å¶æãä¾å¦ï¼æä»¬å¯ä»¥æåè¿ä»£è¿ç¨ï¼è¿ä»£ä¸é¨åï¼ç¶å忢ï¼åä¸äºå
¶ä»å¤çï¼ç¶å忢å¤è¿ä»£ã
å¯è¿ä»£ï¼iterableï¼åç±»æ°ç»ï¼array-likeï¼
è¿ä¸¤ä¸ªå®æ¹æ¯è¯çèµ·æ¥å·®ä¸å¤ï¼ä½å ¶å®å¤§ä¸ç¸åã请确ä¿ä½ è½å¤å åçè§£å®ä»¬çå«ä¹ï¼ä»¥å é ææ··æ·ã
- Iterable å¦ä¸æè¿°ï¼æ¯å®ç°äº
Symbol.iteratoræ¹æ³ç对象ã - Array-like æ¯æç´¢å¼å
length屿§çå¯¹è±¡ï¼æä»¥å®ä»¬çèµ·æ¥å¾åæ°ç»ã
å½æä»¬å° JavaScript ç¨äºç¼å卿µè§å¨æä»»ä½å ¶ä»ç¯å¢ä¸çå®é 任塿¶ï¼æä»¬å¯è½ä¼éå°å¯è¿ä»£å¯¹è±¡æç±»æ°ç»å¯¹è±¡ï¼æä¸¤è å ¼æã
ä¾å¦ï¼åç¬¦ä¸²å³æ¯å¯è¿ä»£çï¼for..of 对å®ä»¬ææï¼ï¼åæ¯ç±»æ°ç»çï¼å®ä»¬ææ°å¼ç´¢å¼å length 屿§ï¼ã
使¯ä¸ä¸ªå¯è¿ä»£å¯¹è±¡ä¹è®¸ä¸æ¯ç±»æ°ç»å¯¹è±¡ãåä¹äº¦ç¶ï¼ç±»æ°ç»å¯¹è±¡å¯è½ä¸å¯è¿ä»£ã
ä¾å¦ï¼ä¸é¢ä¾åä¸ç range æ¯å¯è¿ä»£çï¼ä½å¹¶éç±»æ°ç»å¯¹è±¡ï¼å ä¸ºå®æ²¡æç´¢å¼å±æ§ï¼ä¹æ²¡æ length 屿§ã
ä¸é¢è¿ä¸ªå¯¹è±¡åæ¯ç±»æ°ç»çï¼ä½æ¯ä¸å¯è¿ä»£ï¼
let arrayLike = { // æç´¢å¼å length 屿§ => ç±»æ°ç»å¯¹è±¡
0: "Hello",
1: "World",
length: 2
};
// Error (no Symbol.iterator)
for (let item of arrayLike) {}
å¯è¿ä»£å¯¹è±¡åç±»æ°ç»å¯¹è±¡éå¸¸é½ ä¸æ¯æ°ç»ï¼å®ä»¬æ²¡æ push å pop çæ¹æ³ã妿æä»¬æä¸ä¸ªè¿æ ·ç对象ï¼å¹¶æ³åæ°ç»é£æ ·æä½å®ï¼é£å°±é叏䏿¹ä¾¿ãä¾å¦ï¼æä»¬æ³ä½¿ç¨æ°ç»æ¹æ³æä½ rangeï¼åºè¯¥å¦ä½å®ç°å¢ï¼
Array.from
æä¸ä¸ªå ¨å±æ¹æ³ Array.from å¯ä»¥æ¥åä¸ä¸ªå¯è¿ä»£æç±»æ°ç»çå¼ï¼å¹¶ä»ä¸è·åä¸ä¸ªâçæ£çâæ°ç»ãç¶åæä»¬å°±å¯ä»¥å¯¹å ¶è°ç¨æ°ç»æ¹æ³äºã
ä¾å¦ï¼
let arrayLike = {
0: "Hello",
1: "World",
length: 2
};
let arr = Array.from(arrayLike); // (*)
alert(arr.pop()); // Worldï¼pop æ¹æ³ææï¼
å¨ (*) è¡ç Array.from æ¹æ³æ¥åå¯¹è±¡ï¼æ£æ¥å®æ¯ä¸ä¸ªå¯è¿ä»£å¯¹è±¡æç±»æ°ç»å¯¹è±¡ï¼ç¶åå建ä¸ä¸ªæ°æ°ç»ï¼å¹¶å°è¯¥å¯¹è±¡çææå
ç´ å¤å¶å°è¿ä¸ªæ°æ°ç»ã
妿æ¯å¯è¿ä»£å¯¹è±¡ï¼ä¹æ¯åæ ·ï¼
// å设 range æ¥èªä¸æçä¾åä¸
let arr = Array.from(range);
alert(arr); // 1,2,3,4,5 ï¼æ°ç»ç toString è½¬åæ¹æ³çæï¼
Array.from ç宿´è¯æ³å
许æä»¬æä¾ä¸ä¸ªå¯éçâæ å°ï¼mappingï¼â彿°ï¼
Array.from(obj[, mapFn, thisArg])
å¯éç第äºä¸ªåæ° mapFn å¯ä»¥æ¯ä¸ä¸ªå½æ°ï¼è¯¥å½æ°ä¼å¨å¯¹è±¡ä¸çå
ç´ è¢«æ·»å å°æ°ç»åï¼è¢«åºç¨äºæ¯ä¸ªå
ç´ ï¼æ¤å¤ thisArg å
许æä»¬ä¸ºè¯¥å½æ°è®¾ç½® thisã
ä¾å¦ï¼
// å设 range æ¥èªä¸æä¾åä¸
// æ±æ¯ä¸ªæ°çå¹³æ¹
let arr = Array.from(range, num => num * num);
alert(arr); // 1,4,9,16,25
ç°å¨æä»¬ç¨ Array.from å°ä¸ä¸ªå符串转æ¢ä¸ºå个åç¬¦çæ°ç»ï¼
let str = 'ð³ð';
// å° str æå为å符æ°ç»
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 å
鍿§è¡ç¸åç循ç¯
for (let char of str) {
chars.push(char);
}
alert(chars);
â¦â¦ä½ Array.from ç²¾ç®å¾å¤ã
æä»¬çè³å¯ä»¥åºäº Array.from å建代çæç¥ï¼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 æ©å±å符ç¢çæ¼æ¥çç»æï¼
æ»ç»
å¯ä»¥åºç¨ for..of ç对象被称为 å¯è¿ä»£çã
- ææ¯ä¸æ¥è¯´ï¼å¯è¿ä»£å¯¹è±¡å¿
é¡»å®ç°
Symbol.iteratoræ¹æ³ãobj[Symbol.iterator]()çç»æè¢«ç§°ä¸º è¿ä»£å¨ï¼iteratorï¼ãç±å®å¤çè¿ä¸æ¥çè¿ä»£è¿ç¨ã- ä¸ä¸ªè¿ä»£å¨å¿
é¡»æ
next()æ¹æ³ï¼å®è¿åä¸ä¸ª{done: Boolean, value: any}对象ï¼è¿édone:true表æè¿ä»£ç»æï¼å¦åvalueå°±æ¯ä¸ä¸ä¸ªå¼ã
Symbol.iteratoræ¹æ³ä¼è¢«for..ofèªå¨è°ç¨ï¼ä½æä»¬ä¹å¯ä»¥ç´æ¥è°ç¨å®ã- å
建çå¯è¿ä»£å¯¹è±¡ä¾å¦åç¬¦ä¸²åæ°ç»ï¼é½å®ç°äº
Symbol.iteratorã - å符串è¿ä»£å¨è½å¤è¯å«ä»£ç对ï¼surrogate pairï¼ãï¼è¯æ³¨ï¼ä»£ç对ä¹å°±æ¯ UTF-16 æ©å±å符ãï¼
æç´¢å¼å±æ§å length 屿§ç对象被称为 ç±»æ°ç»å¯¹è±¡ãè¿ç§å¯¹è±¡å¯è½è¿å
·æå
¶ä»å±æ§åæ¹æ³ï¼ä½æ¯æ²¡ææ°ç»çå
å»ºæ¹æ³ã
妿æä»¬ä»ç»ç ç©¶ä¸ä¸è§è ââ å°±ä¼åç°å¤§å¤æ°å å»ºæ¹æ³é½å设å®ä»¬éè¦å¤ççæ¯å¯è¿ä»£å¯¹è±¡æè ç±»æ°ç»å¯¹è±¡ï¼è䏿¯âçæ£çâæ°ç»ï¼å ä¸ºè¿æ ·æ½è±¡åº¦æ´é«ã
Array.from(obj[, mapFn, thisArg]) å°å¯è¿ä»£å¯¹è±¡æç±»æ°ç»å¯¹è±¡ obj 转åä¸ºçæ£çæ°ç» Arrayï¼ç¶åæä»¬å°±å¯ä»¥å¯¹å®åºç¨æ°ç»çæ¹æ³ãå¯éåæ° mapFn å thisArg å
许æä»¬å°å½æ°åºç¨å°æ¯ä¸ªå
ç´ ã
è¯è®º
<code>æ ç¾æå ¥åªæå 个è¯ç代ç ï¼æå ¥å¤è¡ä»£ç å¯ä»¥ä½¿ç¨<pre>æ ç¾ï¼å¯¹äºè¶ è¿ 10 è¡ç代ç ï¼å»ºè®®ä½ ä½¿ç¨æ²ç®±ï¼plnkrï¼JSBinï¼codepenâ¦ï¼