ES5 實現 ES6 生成器 (上)
在編寫生成器的實現程式碼之前,首先來介紹一下生成器。生成器是 ES6 的新特性,可以實現程式碼的暫停,類似於下方的程式碼。
function *func() { console.log("1"); yield; console.log("2"); } var it = func(); it.next();//列印 1 console.log('3'); //列印 3 it.next();//列印 2
這段程式碼的輸出結果是 1、3、2。在這段程式碼中,一共有三點需要注意的地方:
第一點是 * 符號,這是生成器的定義符號。在一個普通的函式宣告中,如果函式名前方有一個 * 符號,就是定義了一個生成器。
第二點是 it = func() ,這裡的 func() 的返回值是一個物件,這個物件是一個迭代器物件,用於控制生成器的暫停與執行。
第三點是 next,程式碼中有兩個 next。第一個 next 用於使生成器開始執行,當執行到 yield 時,生成器就會暫停執行。這時需要 func() 返回的物件再呼叫一次 next ,生成器會繼續執行直到結束或遇到下一個 yield(這段程式碼的生成器中只有一個 yield ,所以執行到結束)
以上是生成器的最簡單的宣告與使用,目前來看生成器就像一個能夠暫停的函式,但生成器不止這一個功能。
生成器還可以進行一個雙向的資料傳遞,比如像下面這樣:
function *func() { var num = yield '傳出的值'; console.log(num); } var it = func(); var val =it.next().value; console.log(val); //列印 '傳出的值' it.next(6);//列印 6
在這段程式碼中有兩個值的傳遞:
第一個是 yield 後面的字串,這個值通過第一個 next 後使用 value 得到。第二個是通過在呼叫 next 是傳入一個值,這個值會代替暫停點yield,賦值到 num。
這個地方有一個順序需要弄清楚,第一個 next 是啟動生成器,到達 yield 就會停止,所以不應該傳入值。第二個 next 由 yield 開始,所以傳入值會“替換”掉 yield。