第十四节:ES6的 Iterator 遍历器到底是什么?
????????對一個事物足夠熱愛,才會有這樣的熱情...
????????
????????沖著這位同學的學習熱情,前端君今晚就給大家再來一發。
for...of為啥不遍歷Object對象
????????第十三節我們講了簡單又實用的for...of,我們可以使用它來遍歷數組,字符串,Set和Map結構,但是有沒有發現,我們并沒有說它可以遍歷Object對象,為什么不試試用它來遍歷Object對象呢?
????????我們試試看:
????//定義一個的Object對象
????let obj = {"name":"前端君"};
????//咱們來for...of一下
????for(let v of obj){
??????? console.log(v);
????}
????//結果:報錯
????//錯誤提示:obj[Symbol.iterator]不是一個function
????????oh no,程序報錯了,for...of根本不支持遍歷普通的Object對象,還出現了錯誤提示:obj[Symbol.iterator]不是一個function,這是什么鬼?
????????為什么數組,Set和Map結構又可以支持for...of的遍歷呢?
????????原來,要想能夠被for...of正常遍歷的,都需要實現一個遍歷器Iterator。而數組,Set和Map結構,早就內置好了遍歷器Iterator(又叫迭代器),它們的原型中都有一個Symbol.iterator方法;而Object對象并沒有實現這個接口,使得它無法被for...of遍歷。
?
????????那么,我們就親自來驗證一下,它們的原型中到底是不是有個叫Symbol.iterator的方法:
? ?? ?//數組
? ?Array.prototype[Symbol.iterator];
? ?//結果:function values(){...}
? ?//字符串
? ?String.prototype[Symbol.iterator];
? ?//結果:function [Symbol.iterator](){...}
? ?//Set結構
? ?Set.prototype[Symbol.iterator];
? ?//結果:function values(){...}
? ?//Map結構
? ?Map.prototype[Symbol.iterator];
? ?//結果:function entries(){...}
? ?//Object對象
? ?Object.prototype[Symbol.iterator];
? ?//結果:undefined
????????從上往下看,確實,唯獨Object對象的原型上沒有Symbol.iterator,返回了:undefined。其他的數據類型的原型上都含有一個名字叫Symbol.iterator的方法Function。
????????注意:Symbol.iterator 是Symbol 對象的 iterator 屬性,是一個特殊的Symbol值,因此,當它作為prototype對象屬性名的時候,獲取它的時候需要使用[ ]的形式: prototype[Symbol.iterator],不能使用點形式獲取:prototype.Symbol.iterator。原因是點形式會把后面的值當作是字符串類型處理,而不是Symbol類型。第十一節有介紹,點擊查看。
?
????????也就說,只要一個數據結構擁有一個叫[Symbol.iterator]()方法的數據結構,就可以被for...of遍歷,我們稱之為:可遍歷對象。比如:數組,字符串,Set和Map結構。
?
????????現在你該知道為什么文章第一個案例會出現錯誤提示:obj[Symbol.iterator]不是一個function 了吧,因為Object對象的原型上壓根就沒有[Symbol.iterator]() 方法啊。還打算報警嗎?
????????既然我們知道擁有[Symbol.iterator]()方法就可以被遍歷,我們就會好奇:[Symbol.iterator]方法到底做了什么這么牛逼,它的原理是什么??
Iterator遍歷器的原理
????????
????????當可遍歷對象被for...of遍歷的時候,[Symbol.iterator]()就會被調用,返回一個iterator對象。其中還有一個很重要的方法:next( );
? ?//數組:一個可遍歷對象
? ?let arr = ['a','b','c'];
? ?//調用數組的Symbol.iterator()方法
? ?let iter = arr[Symbol.iterator]();
? ?iter.next();
? ?//結果:{value: "a", done: false}
? ?iter.next();
? ?//結果:{value: "b", done: false}
? ?iter.next();
? ?//結果:{value: "c", done: false}
? ?iter.next();
? ?//結果:{value: undefined, done: true}
????????第1次調用next( )方法:返回數組的第1個元素:“a”,以及done的值為fasle,表示循環沒有結束,繼續遍歷。
?
????????第2次調用next( )方法:返回數組的第2個元素:“b”,以及done的值還是為fasle,表示循環沒有結束,繼續遍歷。
????????第3次調用next( )方法:返回數組的第3個元素:“c”,以及done的值依然為fasle,表示循環沒有結束,繼續遍歷。
?
????????第4次調用next( )方法:返回的value值為undefined,以及done的值變成了true,表示遍歷結束。
?
????????原來,for...of的原理就是:先調用可遍歷對象的[Symbol.iterator]( )方法,得到一個iterator遍歷器對象,然后就在遍歷器上不斷調用next( )方法,直到done的值為true的時候,就表示遍歷完成結束了。
?
自定義Iterator遍歷器
???
????????既然有了[Symbol.iterator]()方法就算是可遍歷對象,那么我給Object對象手動加上一個[Symbol.iterator]()方法,那么它是不是可以被for...of遍歷了?
????????那我們就試試看,給一個Object對象加一個[Symbol.iterator]( )方法,看它是不是就能被for...of遍歷了?
? ?//定義一個的Object對象
? ?let obj = {
?? ? ?? 0:"我是0",
?? ? ?? 1:"我是1",
??? ? ? 2:"我是2",
??? ? ? length:3,
??? ? ? //添加[Symbol.iterator]方法
? ? ? ?[Symbol.iterator] : function() {
????? ? ??? let _this = this;
????? ? ??? let index = 0;
????? ? ??? return {
?????? ? ?????? next:() => {
???????? ? ???????? let value = _this[index];
??????? ? ????????? let done = (index >= _this.length);
????????????? ? ? ??index++;
????????????? ? ??? return {value,done}
? ????????? ? ??}
??????? ? ? }
??? ? ? }
? ?};
? ?//咱們來for...of一下
? ?for(let v of obj){
??? ? ? console.log(v);
? ?}
? ?//結果:"我是0"
? ?//????? "我是1"
? ?//????? "我是2"
????????上面這個案例也許你看了覺得很復雜,沒看懂,沒關系,我一起來分析它的結構就夠了!
????????我們定義了一個Object對象,同時給它添加了[Symbol.iterator]()方法,并在[Symbol.iterator]()方法實現了next( )方法,next( )方法返回的對象包含了value屬性和done屬性。
????????具體細節如果不理解沒關系,我們確實看到了給Object對象加上了[Symbol.iterator]()方法后,最后確實能被for...of遍歷了。
????????這就是說,我們可以創建一個可遍歷的對象,并且自定義它的遍歷行為。或者說可以通過添加[Symbol.iterator]()方法,把一個不可遍歷的Object對象,變成可遍歷的對象。
Iterator遍歷器的價值?
????????
????????新特性for...of之所以能夠遍歷各種不同的數據結構,正是因為這個數據結構都實現了Iterator遍歷器接口,供for...of遍歷。如果沒有實現Iterator接口,則該數據結構無法被for...of遍歷,比如:普通的Object對象。
?
本節小結
總結:Iterator遍歷器為各種數據結構提供一個統一的遍歷接口,使得for...of能夠輕松簡便地訪問數據成員。 數據結構實現了Iterator接口,我們稱之為可遍歷對象。我們也可以自己創建可遍歷對象并自定義遍歷行為。
總結
以上是生活随笔為你收集整理的第十四节:ES6的 Iterator 遍历器到底是什么?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [云炬创业学笔记]第二章决定成为创业者测
- 下一篇: [云炬创业学笔记]第二章决定成为创业者测