標籤:總結 對象 function 定義 介面 就會 from 沒有 array
1、Generator 函數是 ES6 提供的一種非同步編程解決方案。形式上,Generator 函數是一個普通函數,但是有兩個特徵。一是,function關鍵字與函數名之間有一個星號;二是,函數體內部使用yield語句,定義不同的內部狀態。
2、Generator函數的調用方法與普通函數一樣,也是在函數名後面加上一對圓括弧。不同的是,調用Generator函數後,該函數並不執行,返回的也不是函數運行結果,而是一個指向內部狀態的指標對象,也就是上一章介紹的遍曆器對象(Iterator Object)。
3、必須調用遍曆器對象的next方法,使得指標移向下一個狀態。也就是說,每次調用next方法,內部指標就從函數頭部或上一次停下來的地方開始執行,直到遇到下一個yield語句(或return語句)為止。換言之,Generator函數是分段執行的,yield語句是暫停執行的標記,而next方法可以恢複執行。
4、總結一下,調用Generator函數,返回一個遍曆器對象,代表Generator函數的內部指標。以後,每次調用遍曆器對象的next方法,就會返回一個有著value和done兩個屬性的對象。value屬性工作表示當前的內部狀態的值,是yield語句後面那個運算式的值;done屬性是一個布爾值,表示是否遍曆結束。
5、一個函數裡面,只能執行一次(或者說一個)return語句,但是可以執行多次(或者說多個)yield語句。正常函數只能返回一個值,因為只能執行一次return;Generator函數可以返回一系列的值,因為可以有任意多個yield。
6、由於Generator函數就是遍曆器產生函數,因此可以把Generator賦值給對象的Symbol.iterator屬性,從而使得該對象具有Iterator介面。
var myIterable = {};myIterable[Symbol.iterator] = function* () { yield 1; yield 2; yield 3;};[...myIterable] // [1, 2, 3]
7、yield句本身沒有傳回值,或者說總是返回undefined。next方法可以帶一個參數,該參數就會被當作上一個yield語句的傳回值。
8、下面是一個利用Generator函數和for...of迴圈,實現斐波那契數列的例子。
function* fibonacci() { let [prev, curr] = [0, 1]; for (;;) { [prev, curr] = [curr, prev + curr]; yield curr; }}for (let n of fibonacci()) { if (n > 1000) break; console.log(n);}
9、除了for...of迴圈以外,擴充運算子(...)、解構賦值和Array.from方法內部調用的,都是遍曆器介面。這意味著,它們都可以將Generator函數返回的Iterator對象,作為參數。
function* numbers () { yield 1 yield 2 return 3 yield 4}// 擴充運算子[...numbers()] // [1, 2]// Array.from 方法Array.from(numbers()) // [1, 2]// 解構賦值let [x, y] = numbers();x // 1y // 2// for...of 迴圈for (let n of numbers()) { console.log(n)}// 1// 2
js-ES6學習筆記-Generator函數