generator(生成器)是ES6標準引入的新的數據類型。一個generator看上去像一個函數,但可以返回多次。
我們先復習函數的概念。一個函數是一段完整的代碼,調用一個函數就是傳入參數,然后返回結果:
function foo(x) { return x + x;}var r = foo(1); // 調用foo函數函數在執行過程中,如果沒有遇到return語句(函數末尾如果沒有return,就是隱含的return undefined;),控制權無法交回被調用的代碼。
generator跟函數很像,定義如下:
function* foo(x) { yield x + 1; yield x + 2; return x + 3;}generator和函數不同的是,generator由function*定義(注意多出的*號),并且,除了return語句,還可以用yield返回多次。
大多數同學立刻就暈了,generator就是能夠返回多次的“函數”?返回多次有啥用?
還是舉個栗子吧。
我們以一個著名的斐波那契數列為例,它由0,1開頭:
0 1 1 2 3 5 8 13 21 34 ...
要編寫一個產生斐波那契數列的函數,可以這么寫:
function fib(max) { var t, a = 0, b = 1, arr = [0, 1]; while (arr.length < max) { t = a + b; a = b; b = t; arr.push(t); } return arr;}// 測試:fib(5); // [0, 1, 1, 2, 3]fib(10); // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]函數只能返回一次,所以必須返回一個Array。但是,如果換成generator,就可以一次返回一個數,不斷返回多次。用generator改寫如下:
function* fib(max) { var t, a = 0, b = 1, n = 1; while (n < max) { yield a; t = a + b; a = b; b = t; n ++; } return a;}直接調用試試:
代碼如下:
fib(5); // fib {[[GeneratorStatus]]: "suspended", [[GeneratorReceiver]]: Window}
直接調用一個generator和調用函數不一樣,fib(5)僅僅是創建了一個generator對象,還沒有去執行它。
調用generator對象有兩個方法,一是不斷地調用generator對象的next()方法:
var f = fib(5);f.next(); // {value: 0, done: false}f.next(); // {value: 1, done: false}f.next(); // {value: 1, done: false}f.next(); // {value: 2, done: false}f.next(); // {value: 3, done: true}next()方法會執行generator的代碼,然后,每次遇到yield x;就返回一個對象{value: x, done: true/false},然后“暫停”。返回的value就是yield的返回值,done表示這個generator是否已經執行結束了。如果done為true,則
新聞熱點
疑難解答
圖片精選