迭代器(Iterator) 和 生成器 (Generator) (八)
迭代器與生成器這一章節還沒有看的恨透,只把這一章節的例子全看完了,也看懂了。但是自己寫不出這樣優秀的程式碼。這是我缺少的技能。
// 迭代器(Iterator) 和 生成器(Generator) // 迭代器是一種特殊物件 // 所有的迭代器都有一個next()方法,每次呼叫都返回一個結果物件。結果物件有兩個屬性: 一個是value,表示下一個將要返回的值;另一個是done,它是一個布林型別的值,當沒有更多可以返回資料時返回true // es5 仿製一個迭代器 /*function createInterator(items) { var i = 0;
return { next: function(){ var done = (i>=items.length); var value = !done ? items[i++] : undefined;
return { done: done, value: value }; } } } var iterator = createInterator([1, 2, 3]); console.log(iterator.next()) // "{ value: 1, done: false }"*/
// 生成器是一種返回迭代器的函式 // 通過function關鍵字後的星號(*)來表示,函式中會用到新的關鍵字yield。 //生成器 // 也可以給 函式傳遞一個數組items 迴圈生成 yield items[i] /*function *createInterator() { yield 1; yield 2; yield 3; } // 生成器的呼叫方式與普通函式相同,只不過返回的是一個迭代器 let iterator = createInterator(); console.log(iterator.next()); // 1*/
// yield關鍵字只可在生成器內部使用,在其他地方會導致程式丟擲語法錯誤 // 它與return關鍵字一樣,二者都不能穿透函式的邊界。 // 不能用箭頭函式建立生成器
// 可迭代物件和for-of迴圈 // 可迭代物件具有Symbol.iterator屬性,是一種與迭代器密切相關的物件 // 由於生成器預設會為Symbol.iterator 屬性賦值, 因此所有通過生成器建立的迭代器都是可迭代物件 /*let values = [1, 2, 3]; for(let item of values){ console.log(item) }*/
// 訪問預設的迭代器物件 // 可以用Symbol.iterator屬性,來檢測是否為可迭代物件 // console.log(values[Symbol.iterator]())
// 內建迭代器 // 陣列、Map集合和Set集合都內建了三種迭代器 // 1. entries() 返回一個迭代器,其值為多個鍵值對 // 2. values() 返回一個迭代器,其值為集合的值 // 3. keys() 返回一個迭代器,其值為集合中的所有鍵名 // let values = [1, 2, 3] // console.log(values) // entries() 迭代器 其他迭代器類似 /*let colors = ['red', 'yellow', 'green']; let tracking = new Set([1234, 45678, 9012]); let data = new Map();
data.set("title", "understanding ECMAScript 6"); data.set("format", "ebook");
for(let entry of colors.entries()){ console.log(entry); }
for(let entry of tracking.entries()){ console.log(entry); }
for(let entry of data.entries()){ console.log(data); }*/ // 在for-of迴圈中,如果沒有顯示的指定則使用預設的迭代器 // 陣列和Set集合的預設迭代器是values()方法 // Map集合的迭代器預設的是entries()方法
// 字串迭代器 這個和深入理解es6中的結果不一樣(我在瀏覽器端 嘗試的) /*let str = "a 機 b"; for(let i=0; i<str.length; i++){ console.log(str[i]) }*/
// 高階迭代器的功能 /*function *createInterator() { let first = yield 1; let second = yield first +2; // 4+2 yield second + 3; // 5+3 } let iterator = createInterator(); console.log(iterator.next()); // 1 ... console.log(iterator.next(4)); // 6 ... console.log(iterator.next(5)); // 8 ... console.log(iterator.next());*/ // 由於第一次呼叫next()方法時,無論傳入什麼值都是 輸出1 // 如果給迭代器的next()傳入引數,則這個引數會替代生成上一條yield語句的返回值
/*function run(taskDef) {
// 建立一個無限使用限制的迭代器 let task = taskDef();
// 開始執行任務 let result = task.next();
// 迴圈呼叫next()函式 function step() {
// 如果任務未完成,則繼續執行 if (!result.done) { result = task.next(result.value);
step(); } }
// 開始迭代執行 step(); }
run(function *() { let value = yield 1; console.log(value);
value = yield value + 3; console.log(value); })*/