精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

從理解到實現輕松掌握 ES6 中的迭代器

開發 前端
JavaScript 中除了 Array 之外,ES6 還新增加了 Map、Set 結構,當我們需要操作這些數據時,就需要一種統一的接口來處理這些不同的數據結構。ES6 中新增加的 Iterator(迭代器)就提供了這樣一種機制。

[[352311]]

JavaScript 中除了 Array 之外,ES6 還新增加了 Map、Set 結構,當我們需要操作這些數據時,就需要一種統一的接口來處理這些不同的數據結構。ES6 中新增加的 Iterator(迭代器)就提供了這樣一種機制。

Symbol.iterator 支持的數據結構

ES6 中提供了 Symbol.iterator 方法,該方法返回一個迭代器對象,目前 Array、Set、Map 這些數據結構默認具有 Symbol.iterator 屬性,如下所示,可以看到 Object 類型是沒有的。

  1. console.log([][Symbol.iterator]()); // Object [Array Iterator] {} 
  2. console.log((new Map())[Symbol.iterator]()); // [Map Entries] {  } 
  3. console.log((new Set())[Symbol.iterator]()); // [Set Iterator] {  } 
  4. console.log({}[Symbol.iterator]); // undefined 

除了上面提到這些數據結構,JavaScript 中一些類似數組的對象也默認具有 Symbol.iterator 屬性,例如:字符串、arguments 對象、DOM 的 NodeList 對象。

  • 字符串
  1. const str = 'nodejs'
  2. console.log(str[Symbol.iterator]()); // Object [String Iterator] {} 
  3.  
  4. for (const val of str) { 
  5.   console.log(val); // n o d e j s 
  • arguments 對象
  1. function print() { 
  2.   console.log(arguments[Symbol.iterator]()); // Object [Array Iterator] {} 
  3.   for (const val of arguments) { 
  4.     console.log(val); // n o d e 
  5.   } 
  6. print('n''o''d''e'
  • DOM NodeList 對象
  1. const divNodeList = document.getElementsByTagName('div'
  2. console.log(divNodeList[Symbol.iterator]()) // Array Iterator {} 
  3. for (const div of divNodeList) { 
  4.  // 會輸出每個 div 標簽 
  5.  console.log(div); 

迭代器對象的 next 方法

調用可迭代對象的 Symbol.iterator 方法會返回一個迭代器對象,它的接口中有一個 next 方法,該方法返回 value 和 done 兩個屬性,其中 value 屬性是當前成員的值,done 屬性表示遍歷是否結束。了解生成器函數(Generator)的可能不會陌生,同樣的當你執行一個生成器函數也會得到一個迭代器對象,但是要區分 生成器和迭代器不是一個概念。

  1. const arr = ['N''o''d''e']; 
  2. const iterator = arr[Symbol.iterator](); 
  3.  
  4. console.log(iterator.next()); // { value: 'N', done: false } 
  5. console.log(iterator.next()); // { value: 'o', done: false } 
  6. console.log(iterator.next()); // { value: 'd', done: false } 
  7. console.log(iterator.next()); // { value: 'e', done: false } 
  8. console.log(iterator.next()); // { value: undefined, done: true } 

上例中聲明一個數組 arr,調用 arr 的 Symbol.iterator 方法創建了一個迭代器對象 iterator 之后不斷調用 next 方法返回當前數組內容,直到 next 方法返回值 done 為 true 則該數組訪問完畢。

Iterator 接口遍歷

解構賦值

數組、Set、Map 解構賦值時,會默認調用 Symbol.iterator 方法。注意 Map 調用 Symbol.iterator 方法返回的是一個 entries 方法,該方法返回的是一個新的迭代器對象且按插入順序包含了 Map 對象中每個元素的 [key, value] 數組,所以調用 Map 實例的 keys 或 values 方法也會返回一個新的迭代器對象。

  1. const set = new Set().add('n').add('o'); 
  2. const map = new Map().set('d').set('e'); 
  3. const [xSet, ySet] = set
  4. console.log(xSet, ySet) // n o 
  5. const [xMap, yMap] = map.keys(); 
  6. console.log(xMap, yMap) // d e 

擴展運算符

ES6 中的擴展運算符(...)也會默認調用數組、Set、Map 等結構的 Symbol.iterator 方法。

  1. const set = new Set('node'); 
  2. const [x, y, ...z] = set
  3. console.log(x, y, z); // n o [ 'd''e' ] 

for...of 循環

ES6 借鑒了 C++、Python 等語言引入了 for...of 循環,該循環內部也會調用 Symbol.iterator 方法,只要具有 Iterator 接口的數據結構都可以使用。

  1. const set = new Set().add('n').add('o'); 
  2.  
  3. for (const val of set) { 
  4.   console.log(val); 

for...of 循環在執行中還可以使用 break; 中斷迭代器的執行。以下示例,修改循環語句在執行第一次 val 等于 n 之后執行 break。

  1. for (const val of set) { 
  2.   console.log(val); // n 
  3.   if (val === 'n') break; 

其它方法

數組默認是支持 Iterator 接口,所以任何接收數組做為參數的方法也都會默認調用 Symbol.iterator 方法,如下所示:

  1. const set = new Set().add('n').add('o'); 
  2. console.log(Array.from(set)); // [ 'n''o' ] 
  3. Promise.all(set).then(val => console.log(val)) // [ 'n''o' ] 
  4. Promise.race(set).then(val => console.log(val)) // n 

自定義迭代器

迭代協議

  • 參照可迭代協議,要成為可迭代對象首先要有一個 **@@iterator **即(Symbol.iterator)屬性,該屬性為一個無參數的函數,返回一個符合迭代器協議的對象。
  • 根據迭代器協議定義這個迭代器對象要返回一個 next() 方法,這個 next() 方法返回一個包含 value、done 屬性的對象。
  1. const  myIterator = { 
  2.   // for...of 循環會用到 
  3.   [Symbol.iterator]: function() { return this }, 
  4.    
  5.   // 標準的迭代器接口方法 
  6.   nextfunction() { 
  7.    // ... 
  8.   } 

如果用 TypeScript 寫法描述如下:

  1. // 遍歷器接口 Iterable 
  2. interface Iterable { 
  3.  [Symbol.iterator]: Iterator 
  4.  
  5. // 迭代器對象 
  6. interface Iterator { 
  7.  next(value?: any): IterationResult, 
  8.  
  9. // next 方法返回值定義 
  10. interface IterationResult { 
  11.  value: any
  12.   done: boolean 

基于普通函數的迭代器實現

迭代器的函數實現可以是一個普通函數也可以是一個生成器函數,我們先以普通函數為例,定義一個 Range 構造函數,用來輸出兩個數值區域的所有值。

  1. function Range(start, end) { 
  2.   this.id = start; 
  3.   this.end = end
  4. Range.prototype[Symbol.iterator] = function() { return this } 
  5. Range.prototype.next = function next() { 
  6.   if (this.id > this.end) { 
  7.     return { value: undefined, done: true } 
  8.   } 
  9.  
  10.   return { value: this.id++, done: false } 
  11. const r1 = new Range(0, 3); 
  12. const it = r1[Symbol.iterator]() 
  13. for (const id of r1) { 
  14.   console.log(id); // 0,1,2,3 

基于生成器函數的迭代器實現

使用生成器函數(Generator)實現是最簡單的,只要使用 yield 語句返回每一次的值即可。如下所示:

  1. Range.prototype[Symbol.iterator] = function* () { 
  2.   while (this.id <= this.end) { 
  3.     yield this.id++; 
  4.   } 

異步迭代器

到目前為止我們上面講解的都是同步模式的迭代器,這個很好理解,因為我們的數據源本身也就是同步的,但是在 Node.js 中一次網絡 I/O 請求或者一次文件 I/O 請求,它們都是基于事件是異步的,所以我們就不能像使用 Symbol.iterator 的方式來使用。ECMAScript 2018 標準中提供了 **Symbol.asyncIterator **屬性,這是一個異步迭代器,如果一個對象設置了該屬性,它就是異步可迭代對象,相應的我們要使用 for await...of 循環遍歷數據。

自定義異步迭代器

  1. function Range(start, end) { 
  2.   this.id = start; 
  3.   this.end = end
  4. // 與上面不同,function 前我們增加了 async 關鍵字 
  5. Range.prototype[Symbol.asyncIterator] = async function* () { 
  6.   while (this.id <= this.end) { 
  7.     yield this.id++; 
  8.   } 
  9. const r1 = new Range(0, 3); 
  10. console.log(r1[Symbol.asyncIterator]()); // Object [AsyncGenerator] {} 
  11. for await (const id of r1) { 
  12.   console.log(id); // 0,1,2,3 

與同步迭代器的不同

  • 同步迭代器返回的是一個常規的 { value, done } 對象,而異步迭代器返回的是一個包含 { value, done } 的 Promise 對象。
  • 同步可迭代協議具有 Symbol.iterator 屬性,異步可迭代協議具有 Symbol.asyncIterator 屬性。
  • 同步迭代器使用 for...of 循環遍歷,異步迭代器使用 for await...of 循環遍歷。

異步迭代器的支持目前沒有默認設定了 [Symbol.asyncIterator] 屬性的 JavaScript 內建的對象。不過,WHATWG(網頁超文本應用技術工作小組)Streams 會被設定為第一批異步可迭代對象,[Symbol.asyncIterator] 最近已在設計規范中落地。

下一節我們將會講解異步迭代器在 Node.js 中的使用,歡迎關注。

Reference

[1]你不知道的JavaScript(中卷): https://book.douban.com/subject/26854244/[2]可迭代協議: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Iteration_protocols[3]Symbol.asyncIterator: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator

本文轉載自微信公眾號「Nodejs技術棧」,可以通過以下二維碼關注。轉載本文請聯系Nodejs技術棧公眾號。 

 

責任編輯:武曉燕 來源: Nodejs技術棧
相關推薦

2018-07-16 16:10:03

前端JavaScript面向對象

2024-08-05 00:00:50

ES6JavaScriptClass

2011-05-20 17:10:31

Bing云計算

2022-09-14 08:01:36

JoinMySQL迭代器

2023-03-01 00:07:32

JavaScript迭代器生成器

2023-05-10 08:21:42

Es6Set

2022-06-01 09:06:58

ES6數組函數

2021-08-16 07:05:58

ES6Promise開發語言

2017-08-31 14:25:34

前端JavascriptES6

2020-07-01 07:58:20

ES6JavaScript開發

2022-10-31 16:20:33

JavaScript前端開發

2024-02-27 08:22:56

2020-12-30 15:06:39

開發技能代碼

2018-05-28 09:20:10

Python迭代for循環

2024-06-26 08:18:08

ES6模板字符串

2021-07-30 07:10:07

ES6函數參數

2021-08-07 21:51:17

服務器網站部署

2023-01-12 22:00:48

2021-07-16 07:26:48

ES6javascript開發語言

2025-05-13 08:25:00

模塊化編程JavaScript
點贊
收藏

51CTO技術棧公眾號

一级片免费在线观看视频| 乱一区二区三区在线播放| tube国产麻豆| 国产成人福利av| 欧美色道久久88综合亚洲精品| 欧美一级二级三级| 一级黄色片在线看| 在线亚洲一区| 久久久精品中文字幕| 性欧美丰满熟妇xxxx性久久久| av一区在线播放| 一区二区高清免费观看影视大全| 精品欧美一区二区在线观看视频 | 日韩黄色影院| 成人丝袜高跟foot| 国产日韩精品视频| 亚洲黄色小说图片| 欧美激情五月| 亚洲伦理中文字幕| 日本xxxx免费| 日本成人一区二区| 色乱码一区二区三区88| 久久99久久99精品| а√中文在线8| 欧美国产日韩一二三区| 久久久久高清| 粉嫩av一区二区夜夜嗨| 激情综合色综合久久综合| 欧洲成人在线视频| 日本少妇吞精囗交| 欧美一区二区三区久久精品茉莉花| 日韩久久午夜影院| 中文字幕一区二区人妻电影丶| 欧美国产视频| 欧美性感一区二区三区| jizzjizz国产精品喷水| 暖暖在线中文免费日本| 亚洲欧美一区二区三区极速播放| 视频在线观看成人| 午夜小视频在线播放| 国产成人在线看| 国产精品电影观看| 久久久久久亚洲av无码专区| 亚洲欧美大片| 欧美亚洲一级片| 一级片中文字幕| 国产情侣一区| 97在线免费观看| 永久免费看片在线播放| 亚洲精品1234| 538国产精品一区二区免费视频 | 欧美日韩一区小说| 69久久久久久| 亚洲精品69| 宅男在线国产精品| 日本一本在线视频| 亚洲天堂av资源在线观看| 在线不卡的av| 亚洲精品在线网址| 中文字幕亚洲在线观看| 亚洲成人网在线| 中文字幕一区三区久久女搜查官| 好吊妞国产欧美日韩免费观看网站| 日韩精品一区二区三区老鸭窝| 一区二区三区四区影院| 国产精品xxxav免费视频| 精品国产免费一区二区三区四区 | 97精品国产97久久久久久免费| 国产无遮挡又黄又爽又色| 亚洲国产专区校园欧美| 秋霞av国产精品一区| 黄色污污网站在线观看| 麻豆一区二区三| 亚洲一区二区三区成人在线视频精品 | 欧美.www| 91高潮在线观看| 中文字幕精品无| 激情综合色丁香一区二区| 电影午夜精品一区二区三区| 天堂91在线| 国产精品久久久久久久久免费丝袜| 中文字幕精品一区日韩| 污污的网站在线看| 一本在线高清不卡dvd| 日本三级黄色网址| 超碰成人免费| 伊人青青综合网站| 久草福利资源在线观看| 久久不射2019中文字幕| 国产精品影片在线观看| 亚洲精品一区二区三区新线路| 99国产精品久久久久久久久久久 | 欧美午夜不卡| 57pao成人永久免费视频| 欧美激情一区二区三区免费观看| 国内精品伊人久久久久影院对白| 国产日韩二区| 日本三级在线视频| 欧美日韩加勒比精品一区| 91国内在线播放| 欧美变态网站| 久久精品一本久久99精品| 日韩欧美三级视频| 国产一区二区三区在线看麻豆| 精品蜜桃传媒| av免费在线网站| 在线看日本不卡| 人妻激情偷乱频一区二区三区| 波多野结衣在线观看一区二区| 美女黄色丝袜一区| 波多野结衣黄色网址| 豆国产96在线|亚洲| 亚洲国产精品一区二区第四页av| av老司机免费在线| 在线播放日韩导航| 女人又爽又黄免费女仆| 亚洲欧洲日本一区二区三区| 91久久精品国产| 成年人在线视频免费观看| 五月天国产精品| 日本在线视频播放| 色777狠狠狠综合伊人| 欧美亚洲第一页| 亚洲美女性生活| 亚洲欧美影音先锋| 另类小说色综合| 婷婷精品在线观看| 久久久久亚洲精品成人网小说| 国产又黄又大又爽| 国产精品丝袜在线| 男人插女人下面免费视频| 日韩电影在线观看完整免费观看| 欧美日韩国产999| 国产免费黄色片| 国产精品福利影院| 在线观看免费的av| 色综合天天爱| 国产乱肥老妇国产一区二| 成人动漫在线免费观看| 色老汉一区二区三区| 精品无码一区二区三区| 久久综合图片| 日产国产精品精品a∨| 日韩大片欧美大片| 在线精品国产成人综合| 制服丝袜在线一区| 国产精品日韩精品欧美在线| 色乱码一区二区三区在线| 日韩不卡一区| 国产久一一精品| 成人ww免费完整版在线观看| 欧美一区二区久久| 欧美日韩在线国产| 岛国精品一区二区| 波多野结衣乳巨码无在线| 制服丝袜日韩| 国产精品久久久久久婷婷天堂| 国产三级视频在线看| 欧美亚洲日本国产| 美国黄色片视频| 国产综合久久久久影院| 日本福利视频网站| 乱中年女人伦av一区二区| 欧美一级bbbbb性bbbb喷潮片| 天天爽夜夜爽夜夜爽| 色哟哟精品一区| 99国产精品无码| 国产麻豆欧美日韩一区| 日本一区午夜艳熟免费| 亚洲小说图片| 国产日韩欧美视频| 日韩另类在线| 亚洲男人天天操| 97caocao| 午夜精品久久久久| 中文字幕网站在线观看| 精品一区二区三区在线视频| 97超碰国产精品| 国产成人精品免费视| 成人福利网站在线观看11| 国产在线xxx| 亚洲片av在线| 国产福利第一视频| 欧美性猛交xxxx乱大交极品| 国产白丝一区二区三区 | 国产尤物91| 在线成人视屏| 欧美福利在线观看| 岛国在线大片| 日韩欧美在线观看一区二区三区| 国产精品免费av一区二区| 亚洲国产高清aⅴ视频| 成人啪啪18免费游戏链接| 日韩国产在线观看| 无码av天堂一区二区三区| 教室别恋欧美无删减版| 春色成人在线视频| 亚洲ww精品| 国产91|九色| fc2ppv国产精品久久| 亚洲免费视频网站| 丁香六月色婷婷| 欧美人与z0zoxxxx视频| 五月天激情国产综合婷婷婷| 亚洲人成7777| 欧美丰满老妇熟乱xxxxyyy| 成人激情小说乱人伦| 午夜一级免费视频| 日日夜夜精品视频天天综合网| 国产乱子伦精品视频| 超碰成人久久| 精品亚洲第一| xvideos.蜜桃一区二区| 成人网址在线观看| 91制片厂在线| 99久久婷婷国产综合精品首页| 欧美成人精品一区二区三区| 国内在线免费高清视频| 欧美精品一区二区不卡| 国产欧美久久久| 91福利区一区二区三区| 久久久久久久久久免费视频| 伊人夜夜躁av伊人久久| 97在线观看视频免费| 国产亚洲精品bt天堂精选| 扒开伸进免费视频| 国产一区二区三区在线观看免费| 成年人在线观看视频免费| 久久高清国产| 黄色网页免费在线观看| 伊人蜜桃色噜噜激情综合| 特级西西444| 香蕉综合视频| 一区二区av| jiujiure精品视频播放| 欧美日韩一区综合| 亚洲丝袜啪啪| 欧美人与性禽动交精品| 秋霞在线一区| 久久精彩视频| 日日天天久久| 久草精品电影| 一本色道久久综合亚洲精品酒店| 国产欧美丝袜| 日韩影视高清在线观看| 美乳视频一区二区| 妖精视频一区二区三区免费观看| 久久久久久精| 免费看成人哺乳视频网站| 欧美精品成人一区二区在线观看| 偷拍视屏一区| 免费影院在线观看一区| 国产精品午夜一区二区三区| 青青草久久网络| 色综合蜜月久久综合网| 国产精品一区在线免费观看| 综合激情视频| 日韩 欧美 视频| www.久久久久久久久久| 国产成人亚洲综合a∨婷婷图片| 天天操精品视频| 国产成人免费视频一区| 国产a级黄色片| 久久综合色婷婷| 五月激情四射婷婷| 亚洲男女一区二区三区| 国产一级二级三级| 午夜精品福利一区二区蜜股av| 99精品视频99| 欧美性猛片aaaaaaa做受| 国产精品主播一区二区| 欧美大片在线观看| 免费国产在线视频| 中文字幕在线视频日韩| 超碰免费公开在线| 国内精品中文字幕| 色天使综合视频| 91在线中文字幕| 欧美成人基地| 亚洲精美视频| 亚洲无线一线二线三线区别av| 青青草原av在线播放| 毛片av一区二区三区| 国产乱淫av麻豆国产免费| 久久综合精品国产一区二区三区 | 日韩欧美精品| avav在线播放| 日韩电影在线观看电影| 久久出品必属精品| 久久久久久免费毛片精品| 婷婷激情四射网| 欧美日韩国内自拍| 国产特级aaaaaa大片| 亚洲精品永久免费精品| 激情在线小视频| 热久久这里只有| 日韩精品视频在线看| 日本黑人久久| 亚洲第一网站| 99九九精品视频| 久久久久久久久久久久久久久99| 欧美日韩精品在线观看视频| 在线免费观看日本欧美| 好吊视频一二三区| 久久亚洲欧美日韩精品专区| 日本不卡一二三| 国产青春久久久国产毛片| 91精品国产麻豆国产在线观看| 99999精品视频| 懂色av一区二区三区蜜臀| 91ts人妖另类精品系列| 狠狠色狠狠色综合日日五| 精品二区在线观看| 中文字幕日韩欧美在线视频| 末成年女av片一区二区下载| 亚洲tv在线观看| 日韩精品免费| 国产成人久久777777| 9色porny自拍视频一区二区| 亚洲国产精品久| 91超碰这里只有精品国产| 黄色在线观看网| 欧美整片在线观看| 另类在线视频| 日韩精品在线中文字幕| 国产精品99久久久久久似苏梦涵 | 国产不卡在线| 国产精品嫩草影院一区二区| 亚洲精品456| 亚洲欧洲日产国码无码久久99| 国v精品久久久网| 亚洲av无码一区二区三区在线| 欧美日高清视频| 日本免费在线观看| 国产玖玖精品视频| 欧美超碰在线| 一本色道久久亚洲综合精品蜜桃 | 亚洲最大免费| 久久精品999| 91香蕉视频污在线观看| 欧美日韩一区二区在线观看| aaa在线观看| 国产日产欧美精品| 五月婷婷六月综合| 日本黄色一级网站| 亚洲一区在线电影| 欧美一级淫片免费视频魅影视频| 欧美激情三级免费| 欧美电影在线观看完整版| 97成人在线免费视频| 99精品在线免费| 依依成人综合网| 亚洲欧美www| 日本精品裸体写真集在线观看| 日韩av不卡播放| 男女男精品视频网| 国产精品国产精品88| 日韩一区二区在线看| 福利小视频在线| 久久99精品久久久久久秒播放器| 亚洲永久字幕| 亚洲第一综合网| 91精品国产综合久久久久久漫画 | 这里只有精品在线观看视频| 亚洲超丰满肉感bbw| 欧美女优在线观看| 国产精品天天狠天天看| 最新欧美人z0oozo0| 玖玖爱在线精品视频| 在线观看免费一区| 黄色成人在线| 精品国产乱码久久久久久郑州公司| 性高湖久久久久久久久| 中文字幕第二区| 日韩欧美一级在线播放| 午夜影视一区二区三区| 婷婷久久青草热一区二区| 免费观看在线午夜影视| www日韩欧美| 中文字幕一区二区三区四区久久 | 精品一区电影国产| 国产亚洲精彩久久| 日韩黄色片在线| 久久精品无码一区二区三区| 91成品人影院| 69久久夜色精品国产69| 久久婷婷蜜乳一本欲蜜臀| 少妇极品熟妇人妻无码| 在线免费观看不卡av| 日韩经典av| 亚洲7777| av资源站一区| 国产精品无码专区av免费播放| 性欧美xxxx| 希岛爱理av一区二区三区| 你懂得在线视频| 欧美精品日韩综合在线| 九色porny自拍视频在线观看| 一区二区三区av在线| av中文一区二区三区|