JavaScript Generator 函式
本文將通過簡單程式碼例項詳細介紹一下Generator 函式的用法。
看到文章的標題,估計不少朋友會誤認為它只是一個名稱是Generator的普通函式。
事實並非如此,它並不是一個具體的函式,而是一個全新的非同步程式設計方案,一種新的語法結構。
一.語法分析:
此函式是ES2015新增,是一種全新的非同步程式設計方案,既然叫做函式,那肯定具有函式的一些特點。
Generator函式的特點分析如下:
(1).通過function關鍵字宣告。
(2).function關鍵字與函式名稱之間有一個星號(*)。
(3).函式同樣使用大括號進行包裹。
(4).函式體內允許有yield語句,在普通函式中會報錯。
(5).呼叫函式後,其內部的程式碼並不會理解執行,而是返回一個遍歷器物件。
上面總結了Generator函式的主要特點,都是理論性的闡述,比較抽象,下面通過程式碼例項進行演示。
二.例項分析:
[JavaScript] 純文字檢視 複製程式碼function* antzone() { yield "螞蟻部落一"; yield "螞蟻部落二"; yield "螞蟻部落三"; return "return語句" } let g = antzone();
上面是一段簡單的關於Generator 函式的程式碼例項,下面進行一下分析:
(1).通過function宣告一個名稱為antzone的Generator函式,但是它之間有一個星號。
(2).星號的位置比較靈活,比如可以緊挨著function關鍵字或者緊挨著函式名稱,甚至之間沒有空格都可以。
(3).函式體內具有三條yield語句,它的具體作用後面會有詳細介紹。
(4).最後是return 語句,但是函式呼叫後返回值並不是return 後面的值。
(5).函式返回一個指向內部狀態的指標物件,相當於遍歷器物件。
Generator函式通過yield語句定義一個狀態,return語句也可以定義一個狀態(與普通函式不同)。
上述程式碼中,三個yield語句和一個return語句定義了四個狀態,也就是此函式封裝四個狀態,適合非同步操作。
三.yield語句:
在前文已經介紹,每一條yield定義一個狀態,可以通過遍歷器物件的next方法訪問每一個狀態。
每訪問一個狀態,都要呼叫一次next方法,可以認為yield語句是暫停識別符號,遇到就得暫停執行。
程式碼例項如下:
[JavaScript] 純文字檢視 複製程式碼執行程式碼function* antzone() { yield "螞蟻部落一"; yield "螞蟻部落二"; yield "螞蟻部落三"; return "return語句" } let g = antzone(); console.log(g.next()); console.log(g.next()); console.log(g.next()); console.log(g.next()); console.log(g.next());
程式碼執行效果截圖如下:
程式碼分析如下:
(1).Generator函式中封裝了四個狀態,呼叫函式後返回一個遍歷器物件。
(2).注意呼叫函式後,只是返回一個遍歷器物件,其內部的程式碼並未執行。
(3).在next方法呼叫之前,指標指向函式體內程式碼開始的位置。
(4).第一次呼叫next方法,程式碼從開始位置執行,一直到碰到第一個yield語句,然後返回一個物件,物件具有value和done兩個屬性,value屬性值是當前yield後面表示式的返回值,done的屬性值是一個布林值,如果true表示對yield遍歷介紹,false表示沒結束,很明顯當前沒有結束。
(5).第二個呼叫next方法,程式碼接著執行,直到碰到第二個yield語句,然後返回一個物件,物件value屬性值是螞蟻部落二,done屬性值為false,一直持續下去。
(6).return語句也是一個狀態,與對待yield語句相同,由於它是最後一個了,所以的done屬性值為true。
(7).再執行完return之後,又一次呼叫next方法,因為後面已經沒有yield或者return語句了,可以看到返回物件的value屬性值是undefined,done的屬性值為true。
yield注意細節:
此語句不能用於普通函式,否則會報錯。
如果yield語句位於其他語句中,那麼最好使用小括號包裹:
可以看到上面程式碼報錯了,程式碼修改如下:
[JavaScript] 純文字檢視 複製程式碼function *antzone() { console.log("歡迎來到" + (yield "螞蟻部落")); }
上述程式碼就是正確的,只要將yield語句用小括號包裹起來即可。
但是當此語句作為函式的引數或者在賦值語句中,不使用小括號包裹也是可以的。
[JavaScript] 純文字檢視 複製程式碼func(yield "螞蟻部落"); let antzone = yield;
上面程式碼中,雖然yield語句沒有被小括號包裹,但是並不會報錯。
四.next()方法:
首先,再理一下前面一些相關知識:
(1).呼叫next方法可以返回一個具有兩個屬性的物件。
(2).yield後面的表示式有返回值,但是yield語句本身沒有返回值。
next方法可以接受一個引數,此引數會作為上一個yield語句的返回值。
程式碼例項如下:
[JavaScript] 純文字檢視 複製程式碼執行程式碼function* antzone() { let x=yield "螞蟻部落"; console.log(x==undefined); } let g=antzone(); g.next(); g.next();
程式碼執行效果截圖如下:
上面的截圖證明了這一點,yield語句沒有返回值或者說返回值是undefined。
再通過一段程式碼例項對next方法的引數進行一下演示:
[JavaScript] 純文字檢視 複製程式碼執行程式碼function* antzone(num) { let x = 2 * (yield num); let y = yield x*3; console.log(x,y); } let g=antzone(5); console.log(g.next()); console.log(g.next(2)); console.log(g.next(3));
程式碼執行效果截圖如下:
程式碼分析如下:
(1).呼叫antozne函式,並傳遞引數5,後面會用到。
(2).第一次呼叫next方法,並沒有傳遞任何引數,其實傳遞了也沒用,因為它前面沒有yield語句。
(3).第二次呼叫next方法,傳遞引數為數字2,那麼第一個yield語句的返回值就被設定為2。
(4).於是,x的值等於2*(2),也就是等於4。
(5).第三次呼叫next方法,傳遞引數為數字3,那麼第二個yield語句的返回值就被設定為3。
(6).於是,y的值等於3,所以console.log(x,y)列印結果就是4,3。
考慮到文章的篇幅問題,關於Generator函式的其他知識本文不再做詳細介紹。
更多內容可以參閱如下幾篇文章:
Generator.prototype.throw() 方法一章節。
Generator.prototype.return() 方法一章節。
yield* 表示式一章節。
Generator函式 this一章節。
Generator函式推導(ES2016)一章節。
相關文章
- javascript中generator函式的介紹JavaScript函式
- 學習筆記:javascript中的Generator函式筆記JavaScript函式
- JavaScript非同步程式設計–Generator函式、async、awaitJavaScript非同步程式設計函式AI
- Generator 函式的使用函式
- ES6-Generator 函式 和 async 函式函式
- generator函式與async/await函式AI
- ES6 Generator函式函式
- 生成器函式generator函式
- Node v4 – Generator函式函式
- Generator函式非同步應用函式非同步
- ES6中的迭代器、Generator函式以及Generator函式的非同步操作函式非同步
- 非同步操作系列之Generator函式與Async函式非同步函式
- ES6 Generator 函式介紹函式
- 五分鐘學會generator函式函式
- javaScript函式JavaScript函式
- async、await和generator函式內部原理AI函式
- JavaScript 匿名函式JavaScript函式
- JavaScript function 函式JavaScriptFunction函式
- JavaScript睡眠函式JavaScript函式
- javascript函式(5)JavaScript函式
- javascript-函式表示式JavaScript函式
- [Javascript] Generator & Iterators exerciseJavaScript
- Javascript函式引數求值——Thunk函式JavaScript函式
- JavaScript函式宣告和函式表示式區別JavaScript函式
- ES6的Generator函式(2018-06-21)函式
- JavaScript中的compose函式和pipe函式JavaScript函式
- javascript常用函式大全JavaScript函式
- javascript函式全解JavaScript函式
- JavaScript裡的函式JavaScript函式
- JavaScript 回撥函式JavaScript函式
- JavaScript 建構函式JavaScript函式
- JavaScript | 函式與方法JavaScript函式
- JavaScript 箭頭函式JavaScript函式
- JavaScript回撥函式JavaScript函式
- JavaScript 函式語法JavaScript函式
- javascript函式有哪些JavaScript函式
- Javascript 高階函式JavaScript函式
- 探索es6系列之—-Generator生成器函式函式