詳解JS前端使用迭代器和生成器原理及示例_第1頁
詳解JS前端使用迭代器和生成器原理及示例_第2頁
詳解JS前端使用迭代器和生成器原理及示例_第3頁
詳解JS前端使用迭代器和生成器原理及示例_第4頁
詳解JS前端使用迭代器和生成器原理及示例_第5頁
已閱讀5頁,還剩3頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

第詳解JS前端使用迭代器和生成器原理及示例可迭代對象是什么?

生成器和迭代器的關(guān)系。

讓非迭代對象也可以使用forof進(jìn)行遍歷

for循環(huán)和forin的關(guān)系

總結(jié)

生成器和迭代器這兩個東西平時作為一個切圖仔,一直都沒有使用到。感覺是只有在面試之前才會的東西。面試過不了幾天,再次看這兩個詞一陣恍惚。

記憶力退化成這樣了么?最大的原因一定是用得少了。然后呢?就是沒有真正的理解它們。我對于它們的認(rèn)知常常有下面這些:

1.我常常把迭代器和生成器理解成完全不同的東西。

2.我常常把for、forEach、map、reduce和forof混為一談

3.我常常把數(shù)組、類數(shù)組認(rèn)為是可迭代對象

想來要真正的記住它,增加自己的武器庫,必須要弄明白這些東西才行。

我們首先是要搞明白什么forof是干什么用的。

業(yè)務(wù)代碼確實使用不上,但是如果不理解的話,等真到了可以使用的場景的時候,又是否真的能夠運(yùn)用起來,甚至記起來呢?

forof是干什么用的

所有人都知道一些概念for、forEach、map、reduce這些是可以遍歷數(shù)組的,forof是用于遍歷迭代對象的。如下:

constarr=[1,2,3]

arr.forEach((item,index)={

console.log(item)//1,2,3

console.log(index)//0,1,2

而巧合的是forof也可以遍歷數(shù)組

for(letkeyofarr){

console.log(key)//123

將arr改變?yōu)閏onstobj={a:1,b:2,c:3}的時候,兩者都沒有遍歷出結(jié)果。

前者是沒有反應(yīng),后者會直接報錯:TypeError:objisnotiterable。翻譯一下,類型錯誤:obj不是一個可迭代對象。

那么什么是可迭代對象呢?

可迭代對象是什么?

我們先來看看下面這個例子:

constitemLi1=document.getElementByTagName(li)

constitemLi2=document.querySelectorAll(li)

for(letkeyofitemLi1){

console.log(item)

for(letkeyofitemLi2){

console.log(item)

也就是說HTMLCollection和NodeList是可以迭代對象。其他的可迭代對象有Array、map、set、string等等。如果說類數(shù)組的話,是不是迭代對象呢?

constarrLike={

0:1,

1:2,

2:3,

lenght:3

for(leti=0;iarrLike.length;i++){

console.log(arrLike[i])//1,2,3

for(letofarrLike){

console.log(key)//uncachhTypeError:objisnotiterable

for循環(huán)打印出了對應(yīng)的結(jié)果,而forof報錯了。類數(shù)組不是可迭代的的對象。這又是為什么呢?我們將類數(shù)組和HTMLCollection類型打印出來比較一下。

而類數(shù)組如下:

它們有一個明顯的不同,可迭代對象的原型鏈上面是包括Symbol.iterator的。而這個就是讓數(shù)組變成可迭代的根本原因。

也就是說,當(dāng)目的對象的原型鏈上面包括Symbol.iterator的時候,它才是可迭代對象。

對象是無序的,無序的東西自然不可以迭代

這里使用到了Symbol類型,它在MDN上面的解釋就是用于生成全局唯一的變量。而可迭代對象就是它的使用場景。受它的啟發(fā),我們在業(yè)務(wù)當(dāng)中,如果需要前端來生成一個唯一ID的時候,再次之前,通常都是創(chuàng)建一個UUID的函數(shù)來生成一個唯一ID。Symbol不用這么麻煩,直接使用就可以了。

由此可知,Atotype[Symbol.iterater]這個函數(shù)封裝了一些東西,使得forof可以將對象的元素給打印出來。

換一句話來說,就是Atotype[Symbol.iterater]=function(){}的執(zhí)行生成一個迭代器對象。

也就是說,當(dāng)Ototype也有[Symbol.iterater]的方法的時候,forof也能夠遍歷它呢?我們來試試看吧。

Object.ptotoype[Symbol.iterator]=functionvalue(){}

這不就是生成器的作用么?

生成器和迭代器的關(guān)系。

ES6給我提高了一個生成器的函數(shù)。既然叫做生成器,它生成的東西就是迭代器。

表現(xiàn)形式如下:

function*generation(iterableObject){

for(leti=0;iiterableObject;i++){

yielditerableObject[i]

由*符號和yield關(guān)鍵字組成。

當(dāng)constiterator=generation([1,2,3]),其執(zhí)行流程如下:

iterator.next()=={value:1,done:false}

iterator.next()=={value:2,done:false}

iterator.next()=={value:3,done:false}

iterator.next()=={value:undefined,done:true}

到了第四次,value為undefined的時候,done為true(也就是說,當(dāng)done為true的時候,value一定為undefined)。所以說,yield的作用有兩個:

生成一個值,將該值封裝成一個對象,而這個對象是{value:..,done:flase/true}這樣的形式。

可以明顯的看出來,生成器有一個作用,通過next這個接口,可以看到迭代的過程。

既然說生成器生成了一個迭代器,那么是不是說生成器執(zhí)行后的結(jié)果就是一個迭代器呢?既然是迭代器,自然就可以被forof給遍歷。

for(constkeyofgeneration([1,2,3]){

console.log(key)//1,2,3

果然可以。

經(jīng)典面試題:自己實現(xiàn)一個next這樣的接口呢?

上面已經(jīng)有了實現(xiàn)的思路。通過一個標(biāo)識符和一個判斷就能夠使用ES5來使用,如下代碼片段。

functiongeneration(iterableObj){

letnextIndex=0

functionnext(){}

return{

next:()={

returnnextIndexiterableObj.length

{value:iterableObj[nextIndex++],done:false}

:{value:undefined,done:true}

當(dāng)nextIndex下于數(shù)組長度的時候,沒有迭代完畢。

注意:nextIndex++是先跑nextIndex,再自增。

何為接口,后臺給你一個url地址,這個是網(wǎng)絡(luò)接口。next是設(shè)計師給你封裝的一個方法,你通過這個方法來達(dá)到上吧yield的兩個作用,所以next()也是一個接口,前端接口。簡單來說,一個封裝好的方法就是一個接口。

讓非迭代對象也可以使用forof進(jìn)行遍歷

正如第一節(jié)所說,Symbol.iterator的方法是迭代器的關(guān)鍵。那么我們也可以給Object掛載上該方法。既然該方法可以讓對象變成迭代器,就可以直接使用上面ES5實現(xiàn)next方法的代碼片段。

constobj={

a:1,

b:2,

c:3

Ototype[Symbol.iterator]=functionvalue(){

constkeys=Object.keys(Object(this))

letnextIndex=0

functionnext(){

returnnextIndexkeys.length

{value:[keys[nextIndex],obj[keys[nextIndex++]]],done:false}

:{value:undefined,done:true}

return{

next

for(const[key,value]inobj){

console.log(key)

for循環(huán)和forin的關(guān)系

for循環(huán)和forin看著很像,其實只是共用了for這個關(guān)鍵字,它們都是JS

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論