筆記整理自:廖雪峰老師的JS教程
目錄
簡介
generator(生成器)是ES6標准引入的新的數據類型。一個generator看上去像一個函數,但可以返回多次。
與函數的不同之處
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) {
[a, b] = [b, a + b];
arr.push(b);
}
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 = 0;
while (n < max) {
yield a;
[a, b] = [b, a + b];
n ++;
}
return;
}
generator寫完后直接調用試一下: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: false}
f.next(); // {value: undefined, done: true}
next()
方法會執行generator的代碼,然后,每次遇到yield x;
就返回一個對象{value: x, done: true/false}
,然后“暫停”。返回的value
就是yield
的返回值,done
表示這個generator是否已經執行結束了。如果done
為true
,則value
就是return
的返回值。
當執行到done
為true
時,這個generator對象就已經全部執行完畢,不要再繼續調用next()
了。
for ... of
循環調用
for (var x of fib(10)) {
console.log(x); // 依次輸出0, 1, 1, 2, 3, ...
}
這種方式不需要我們自己判斷done
。