国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

遍歷得到數組 Or Iterator 遍歷器?

開發 前端
熟悉 ES 語法數據結構的朋友一定很清楚,原生對象數據結構并不支持 obj.keys()、obj.values()和 obj.entries() 方法,數組與 map、set 等數據結構才支持。但仍可以通過 Object.keys(obj)、Object.values(obj)、Object.entries(obj)獲取原生對象中可遍歷的屬性組成數組類型數據結構。

[[433429]]

一、背景

故事的開頭是這樣的...

在遍歷數組與對象屬性時,對使用 obj.keys()、obj.values()和 obj.entries() 還是 Object.keys(obj)、Object.values(obj)、Object.entries(obj)方法產生了一些困惑。話不多說,先放問題:

需求:想要遍歷一個對象,并獲取遍歷對象的屬性值 實現:Object.keys()、Object.values() 和 Object.entries() 方法 問題:一不小心同數組的 entries(),keys()和 values() 方法混淆了~QAQ

二、keys()、values()、entries()遍歷方法

熟悉 ES 語法數據結構的朋友一定很清楚,原生對象數據結構并不支持 obj.keys()、obj.values()和 obj.entries() 方法,數組與 map、set 等數據結構才支持。但仍可以通過 Object.keys(obj)、Object.values(obj)、Object.entries(obj)獲取原生對象中可遍歷的屬性組成數組類型數據結構。

也就是說,keys()、values()和 entries() 方法有兩種:

ES5-ES2017 相繼引入 Object.keys 、Object.values 和 Object.entries 方法,返回一個數組,成員是參數對象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵名/鍵值/鍵值對,可以用 for...of 循環進行遍歷;

ES6 提供 entries(),keys() 和 values() -- 可用于遍歷數組/Map/Set 等類數組數據結構實例,返回一個(Iterator)遍歷器對象,可以用 for...of 循環進行遍歷。

注意這里又有兩點區別:

兩者調用語法不同,顯而易見;

前者返回的是一個可迭代的對象,而后者返回的是一個真正的數組。

有沒有被繞暈?那我們先來看第一個問題吧 -- 調用語法的不同

Q1: Object.keys 、Object.values 和 Object.entries 方法

為了區分這兩種調用語法,我們必須得來回顧下原型鏈的相關知識。

因為這里的 entries(),keys()和 values() 方法正是是調用原型對象構造函數上的方法。如下圖可以看到,對于一個普通對象,這三個方法在 Object 對象的[[prototype]]下的 constructor 中:

而對于一個數組結構來說,這三個方法可以在數組原型鏈中和原型鏈上層對象原型的 constructor 中同時找到:

即 Object.keys(arr)調用的是數組原型鏈頂層原型對象 constructor 的方法,而數組本身也支持的 arr.keys()方法,則是調用數組原型鏈上的方法。

即對象只支持前種調用方式,而數組同時支持這兩種調用:

同時我們知道在 JavaScript 中,對象是所有復雜結構的基礎。也正對應了其他復雜結構原型鏈的頂端是對象原型結構。現在應該能夠知道為何普通對象不支持 obj.keys()、obj.values()和 obj.entries() 方法了,但到這里就不得不提出另一個疑問了:

Q2: 如何讓一個對象支持 obj.keys()、obj.values()和 obj.entries() 方法呢?

理論上,我們是可以為一個對象構造任意方法,那么如何實現和數組一樣的遍歷方法呢?本質上這個方法是能夠生成一個遍歷器。

  1. let objE = { 
  2.   data: [ 'hello''world' ], 
  3.   keys: function() { 
  4.     const self = this; 
  5.     return { 
  6.       [Symbol.iterator]() { 
  7.         let index = 0; 
  8.         return { 
  9.           next() { 
  10.             if (index < self.data.length) { 
  11.               return { 
  12.                 value: self.data[index++], 
  13.                 done: false 
  14.               }; 
  15.             } 
  16.             return { value: undefined, done: true }; 
  17.           } 
  18.         }; 
  19.       } 
  20.     } 
  21.   } 
  22. }; 

上述,我們自己創建了一個 data 對象,并實現了它自己的 data.values() 方法。同時,我們依然可以對它調用 Object.values(data) 方法。

從上面的方法不難看出,我們在對象中通過添加 Symbol.iterator 手動構造了一個輸出遍歷器函數,關于遍歷器的討論我們在下一節討論,現在先來討論調用返回結果的區別。

Q3: 兩種調用方法返回結果:遍歷器與數組

1)第一種調用方法,根據定義可知:返回一個數組,數組成員是參數對象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵名/鍵值/鍵值對。

敲重點!!!這三個方法只返回對象自身的可遍歷屬性,即屬性描述對象的 enumerable 為 true。

我們可以通過 for ... in 循環來實現相同的遍歷效果。

2)而第二種方法,返回一個遍歷器:顧名思義,遍歷器也可以滿足循環遍歷的需求。

本質上,遍歷器的定義是一種接口,為各種不同的數據結構提供統一的訪問機制。接下來就來了解下適用于不同數據結構的遍歷器。

三、Iterator 遍歷器

首先我們知道,目前主要有四種表示“集合”的數據結構:數組(Array)、對象(Object)、Map 和 Set,這里表示"集合"的對象例如 NodeList 集合類數組對象,而遍歷器可以使我們遍歷訪問這些集合。

實際上,原生具備 Iterator 接口的數據結構包括 Array、Map、Set、String、TypedArray、函數的 arguments 對象和 NodeList 對象。

具體遍歷器的概念可參考阮一峰老師 ES6 入門 Iterator 一章,已經十分詳細清楚:

因此,Iterator 遍歷器本質上為所有數據結構,提供了一種統一的訪問機制,即 for...of 循環。

關于遍歷,我們前面已經講到了遍歷對象屬性,這里再提一嘴:

1. 遍歷類數組對象/Array/Map/Set 等數組數據結構實例

當使用 for...of 循環遍歷某種數據結構時,該循環會自動去尋找 Iterator 接口。一種數據結構只要部署了 Iterator 接口,我們就稱這種數據結構是“可遍歷的”(iterable)。ES6 規定,默認的 Iterator 接口部署在數據結構的 Symbol.iterator 屬性,換句話說,一個數據結構只要具有 Symbol.iterator 屬性,就可以認為是“可迭代/遍歷的”(iterable)。

2. 獲取對象可遍歷屬性

Object.keys 、Object.values 和 Object.entries 方法只返回對象自身的可遍歷屬性,通過屬性描述對象的 enumerable 標識改對象屬性是否可以遍歷。同時因為普通對象 not iterable,即普通對象不具有 Symbol.iterator 屬性,所以無法通過 for...of 循環直接遍歷,否則會報錯 Uncaught TypeError: obj is not iterable。

可見,數組及類數組的遍歷(迭代)與普通對象中的提到的遍歷是不同的,這分別取決于各自的 iterable 和 enumerable 屬性。

3. for ... of

ES6 中引入 for...of 循環,很多時候用以替代 for...in 和 forEach() ,并支持新的迭代協議。for...of 語句在可迭代對象上創建一個迭代循環,調用自定義迭代鉤子,并為每個不同屬性的值執行語句。

那么終極問題:如何實現 Symbol.iterator 方法,使普通對象可被 for of 迭代?其實在 Q2 部分已經實現了。

嘗試給普通對象實現一個 Symbol.iterator 接口:

  1. // 普通對象 
  2. const obj = { 
  3.   foo: 'value1'
  4.   bar: 'value2'
  5.   [Symbol.iterator]() { 
  6.     // 這里 Object.keys 不會獲取到 Symbol.iterator 屬性 
  7.     const keys = Object.keys(obj); // 得到一個數組 
  8.     let index = 0; 
  9.     return { 
  10.       next: () => { 
  11.         if (index < keys.length) { 
  12.           // 迭代結果 未結束 
  13.           return { 
  14.             value: this[keys[index++]], 
  15.             done: false 
  16.           }; 
  17.         } else { 
  18.           // 迭代結果 結束 
  19.           return { value: undefined, done: true }; 
  20.         } 
  21.       } 
  22.     }; 
  23.   } 
  24. for (const value of obj) { 
  25.   console.log(value); // value1 value2 
  26. }; 

for...of 循環內部調用的是數據結構的 Symbol.iterator 方法,for...of 循環可以使用的范圍包括數組、Set 和 Map 結構、某些類似數組的對象(比如 arguments 對象、DOM NodeList 對象)、后文的 Generator 對象,以及字符串。

for...of 循環作為 ES6 新引入的一種循環,具有以下明顯優勢(按需使用):

有著同 for...in 一樣的簡潔語法,但是沒有 for...in 那些缺點(無序,不適用于遍歷數組)。

不同于 forEach 方法,它可以與 break、continue 和 return 配合使用。

提供了遍歷所有數據結構的統一操作接口。

以上是我從 keys()、values()、entries() 遍歷方法出發對遍歷器產生的幾點思考,如有不足之處,歡迎指正~~~

 

責任編輯:武曉燕 來源: 微醫大前端技術
相關推薦

2009-11-17 15:07:16

PHP數組遍歷

2009-11-16 16:23:10

PHP數組遍歷

2021-03-29 12:01:00

遍歷數組for循環

2019-07-25 10:08:05

JavaScript數組轉換

2025-08-06 06:10:00

JavaScrip數組for 循環

2009-09-08 09:59:26

LINQ遍歷多個數組

2009-11-17 15:00:19

PHP遍歷數組

2024-04-25 07:54:46

遍歷數組PythonFor循環

2022-09-07 11:52:48

forforEach前端

2023-11-07 10:10:36

設計模式元素

2021-02-05 23:08:10

JS代碼循環

2021-06-15 10:01:27

JavaScript數組遍歷Entries

2021-06-18 10:05:14

JavaScript數組遍歷

2020-06-30 10:37:55

JavaScript開發技術

2021-01-11 07:51:16

DOM對象節點樹

2021-08-02 10:01:09

Iterator接口Java項目開發

2009-09-16 17:21:53

LINQ遍歷

2022-10-26 09:27:59

Python編程迭代器協議

2021-07-22 07:20:24

JS 遍歷方法前端

2011-11-02 17:17:06

jQuery
點贊
收藏

51CTO技術棧公眾號

2024最新电影在线免费观看| 视频一区二区三区国产| www.国产区| 在线视频亚洲欧美中文| 亚洲视频在线观看一区| 97视频国产在线| 你懂的在线视频| 成人精品高清在线| 91免费视频网站| 日韩亚洲国产免费| 亚洲精品乱码久久久久久黑人| 豆国产97在线| 欧美色婷婷久久99精品红桃| 精品伦理精品一区| 精品乱人伦小说| 免费男女羞羞的视频网站中文字幕| 国产探花一区| 日日骚久久av| 亚洲香蕉成视频在线观看| 91av资源在线| 欧美婷婷六月丁香综合色| 一不卡在线视频| 欧美日韩综合视频| 国产日本在线视频| 久久人人看视频| 成人动漫一区二区在线| 手机av在线| 欧美专区一二三| 日韩av一级片| 激情综合色综合啪啪开心| 久草在线视频网站| 国产999在线| 久久99青青| 丰满女人性猛交| 中文字幕欧美一区| 天堂电影一区| 一区二区不卡在线视频 午夜欧美不卡' | 久久国产精品久久精品| 成人性色生活片免费看爆迷你毛片| 3344国产永久在线观看视频| 日本一区二区视频| 夜夜嗨av一区二区三区| 免费中文字幕日韩欧美| 亚洲一区资源| 精品3atv在线视频| 国产区av在线| 视频免费观看| 久久av秘一区二区三区| 亚洲激情自拍| 日本精品一区二区三区视频| 欧美刺激午夜性久久久久久久| 一区二区三区| 91久久亚洲| 国产一区影院| 一级二级在线观看| 一区二区三区视频在线| 欧美精品偷拍| 成人ssswww在线播放| 亚洲一区二区三区成人| 精品福利在线导航| 亚洲女同一区二区| 午夜精品久久久久99热蜜桃导演| 99热在线免费| av免费观看久久| 亚洲影视在线观看| 日本国产亚洲| 青青青手机在线视频观看| 欧美性大战xxxxx久久久| 午夜精品久久99蜜桃的功能介绍| 妞干网在线观看视频| 欧美日韩国产高清一区二区| 成人福利视频网站| 国产综合欧美| 欧美成年网站| 性生大片免费观看性| 韩国一区二区电影| 欧美日韩精品是欧美日韩精品| 国内外成人在线| 日韩欧美在线中字| 成人性生交大片免费看午夜| 欧美成人一品| 成人超碰在线| 欧美巨乳在线| 一级在线免费视频| 嫩草影院中文字幕| 成人免费xxxxx在线观看| 亚洲sss视频在线视频| 9久草视频在线视频精品| 波多野结衣在线观看一区二区三区| 尤物在线网址| 91国视频在线| 国产精品国产三级国产专播精品人 | 亚洲精品videossex少妇| 中文字幕巨乱亚洲| 国产精品热久久久久夜色精品三区| 亚洲专区**| 五月天国产在线| 成人亚洲欧美| 999福利在线视频| 免费观看羞羞视频网站| 久久久久se| 亚洲女人被黑人巨大进入al| 日韩精品视频免费专区在线播放| 欧美午夜精彩| 日韩大胆视频| 久久av一区二区| 亚洲欧美国产一本综合首页| 亚洲国产精品久久艾草纯爱| 久久成人羞羞网站| 日韩精品第一区| 日本一区二区三区中文字幕| 中文字幕在线免费专区| 国产精品视频二| 天堂一区二区三区| 国产日韩精品视频| 在线精品高清中文字幕| 欧美老年两性高潮| 亚洲免费在线视频| 久久亚洲一区二区三区明星换脸| 欧美a级黄色大片| 亚洲国产精品va在线看黑人 | 久久99视频精品| 日韩精品在线免费观看视频| 欧美性淫爽ww久久久久无| 一级女性全黄久久生活片免费| 国产精品午夜在线观看| 国产成人aaaa| 91一区二区三区在线观看| 成人亚洲一区二区一| 欧美亚洲一区二区三区| 久久激情网站| 久久久久欧美精品| 国产精品自产自拍| 国产一区二区三区美女| 成人妖精视频yjsp地址| 激情视频免费| 九色丨porny丨| 2019一级黄色毛片免费看网| 成人午夜激情av| 国产视频一视频二| 国产高清在线一区| 国产伦精品一区二区三区高清 | 午夜亚洲福利| 亚洲大片在线| 中文字幕在线看| yourporn在线观看中文站| 黄视频网站在线| 亚洲一区二区电影| 激情成人亚洲| 寂寞少妇一区二区三区| 久久亚洲精精品中文字幕早川悠里| 久久天堂精品| heyzo高清国产精品| 免费h视频在线观看| 在线看成人短视频| 亚洲精品国产日韩| 91在线一区二区| 日韩三级视频中文字幕| 久久久综合免费视频| 成人av资源网| 黄色三级在线观看| jizz亚洲| 精品国产a一区二区三区v免费| 成人h动漫免费观看网站| 亚洲精品欧美| 黑人狂躁日本妞一区二区三区 | 99porn视频在线| 亚洲 中文字幕 日韩 无码| 天天在线女人的天堂视频| 成人影院网站| 石原莉奈一区二区三区在线观看| 国产偷国产偷精品高清尤物| 欧美成人精品3d动漫h| 国产毛片在线看| 久久免费视频观看| 日韩av大全| 你懂的在线免费观看| 91精品久久久久久综合五月天| 99国产精品视频免费观看一公开 | 色天天综合狠狠色| 亚洲国产欧美不卡在线观看| 婷婷亚洲一区二区三区| 欧美在线色图| 亚洲成人免费观看| 国产精品视频99| 91短视频在线| 亚洲欧美综合久久久| 午夜a成v人精品| 国产精品三区四区| 猫咪在线永久网站| 91久久夜色精品国产九色| 欧美一个色资源| www.夜夜爱| 久本草在线中文字幕亚洲| 最近中文字幕一区二区三区| 国模精品视频一区二区三区| 亚洲一区二区三区成人| 欧美1区2区| 精品视频久久久久久| 成人性做爰aaa片免费看不忠|