ES 6サブジェネレータ(Iterator)とジェネレータ(Generator)

25723 ワード

普段私たちが一番多く使っているのはforサイクルです.
簡単な例を見てください.
     var colors = ["red", "green", "blue"];
      for (var i = 0, len = colors.length; i < len; i++) {
          console.log(colors[i]);
      }
上述のようにループは簡単であるが、複数のループネストを使用すると、各ループに変数を定義する必要があり、反復を実行するたびにセット内の位置を記録するために、他のforループの変数を誤って使用してしまい、プログラムエラーが発生します.しかし、シーケンサは動作を簡単にすることができます.プログラムの異常を低減します.次は一緒に何かを見ましょう.
一、何がサンデーですか?
ローズマリー:特殊なオブジェクトです.彼は特別な反復プロセスのために設計された専用インターフェースを持っています.すべてのローズマリーオブジェクトにはnext()の方法があります.毎回呼び出したら、結果の対象に戻ります.その結果、オブジェクトは2つの属性があります.一つはvalueで、次の戻り値を表します.もう一つはdoneであり、彼はブールタイプの値であり、戻り可能なデータがない場合はtrueに戻り、反復終了を暗示している.
今はECMAScript 5の文法を使って、ディエゼルを構築しています.
 function createIterator() {
       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}"
 console.log(iterator.next());// "{value:2,done:false}"
 console.log(iterator.next());// "{value:3,done:false}"
 console.log(iterator.next());// "{value:undefined,done:true}"
 //            ,                
 console.log(iterator.next());// "{value:undefined,done:true}"
 
この例では、createIterator()方法は、next()方法を有するオブジェクトに戻り、next()方法を呼び出すたびに、iは、現在の参加の長さに等しいかどうかを判断する.donetrueより大きい場合はdoneとなり、その逆もまた然りである.次にtrueを反に取ります.doneがvalueである場合、undefinedi+1,に割り当てられる.そうでなければ、itemは、valueに対して、スケーリングされた値を再取得し、functionに対応する.実際にはES 6ローズマリーの原理とケースも似ています.
二、何がジェネレータですか?
生成器は、*キーワードの後の星番号(yield)によって表されるローズマリーに戻る関数であり、関数には新しいキーワードfunctionが使用される.星番号はyieldにくっついてもいいし、中にスペースを追加してもいいです.
	//  createIterator()   *          
    function *createIterator() {
       yield 1;
       yield 2;
       yield 3;
    }
  //              ,            
  var iterator = createInterator();
  console.log(iterator.next().value); // 1
  console.log(iterator.next().value); // 2
  console.log(iterator.next().value); // 3    
  
なお、関数は、yield 1乬が実行されるたびに自動的に停止する.上記の例のように、関数初期化がnext()を実行した後、関数は、ローズマリーのyield 2メソッドを再起動するまで、下のfunciont *(){}ステートメントを実行し続けることができない.
三、ジェネレータ関数式
シンタックスfunctionキーワードと小かっこの中に星番号を追加します.
判例を見ます
let createator = function *(items){
	for(let i = 0; i<items.length; i++){
		yield iems[i];
	}
}

let iterator = createIterator([1,2,3]);

console.log(iterator.next()); // "{value:1,done:false}"
console.log(iterator.next()); // "{value:2,done:false}"
console.log(iterator.next()); // "{value:3,done:false}"
console.log(iterator.next()); // "{value:undefined,done:true}"

//                 
console.log(iterator.next()); // "{value:undefined,done:true}"

この例ではcreateator ()は、一般的な関数ではなく、ジェネレータ関数式である.矢印関数を使ってジェネレータを作成してはいけません.
生産器対象の方法
1、ECMAScript 5オブジェクトの字面量スタイルを使用してジェネレータオブジェクトを定義します.

let obj = {
	createIterator:function *(items){
		for(let i=0; i<items.length; i++){
			yield items[i];
		}
	}
}

let iterator = obj.createIterator([1,2,3]);

実は上の判例はECMAScript 6で関数の説明方法を説明して書き換えることができます.
let obj = {
	*createIterator(items){
		for(let i=0; i<items.length; i++){
			yield items[i];
		}
	}
}

let iterator = obj.createIterator([1,2,3]);

これは普通の関数申明と似ていますか?実は*は、* createIterator(items)のように、方法名とスペースを残しても良い.でも、一緒にいるほうがいいと思います.
反復可能なオブジェクトとfor-of
反復可能なオブジェクトはSymbol.iterator属性を持っています.Symbol.iteratorは、指定された関数によって、付属のオブジェクトとして働くディズエ代数器を返すことができます.エス6内のすべての集合オブジェクト(配列、set、mapセット)と文字列は反復可能なオブジェクトであり、これらのオブジェクトにはデフォルトのローズマリーがあります.
デフォルトのローズマリーにアクセスします.
let values = [1,2,3];
let iterator = values[Symbol.iterator];

console.log(iterator.next()); // "{value:1,done:false}"
console.log(iterator.next()); // "{value:2,done:false}"
console.log(iterator.next()); // "{value:3,done:false}"
console.log(iterator.next()); // "{value:undefined,done:true}"
例では、Symbol.iteratorを介して配列のvaluesのデフォルトのディナリーを取得し、配列中の要素を巡回します.JavaScriptエンジンでfor-ofサイクルステートメントを実行する場合も同様の処理があります.
次に、ECMAScriptの新しい特性for-ofを見ます.
let values = [1,2,3];
for(let num of values){
	console.log(num);
}
上のコードは1 2 3を出力します.
このfor-ofサイクルは、実行するたびに反復可能なオブジェクトのnext()方法を呼び出し、その結果オブジェクトのvalue属性を変数に格納します.このプロセスを継続的に実行すると、エンがオブジェクトに戻るdone属性の値がtrueであることが分かります.Symbol.iteratorを使用して、オブジェクトが反復可能なオブジェクトかどうかを確認します.
function isIterable(object){
	return typeof object[Symbol.iterator] === "function";
}

console.log(isIterable([1,2,3])); // true
console.log(isIterable("hello")); // true
console.log(isIterable(new Map())); // true
console.log(isIterable(new Set())); // true
console.log(isIterable(new weakMap())); // false
console.log(isIterable(new weakSet())); // false

前の例のfor-ofサイクル実行前にも同様の対象検査を行います.
  • 今日は簡単な理解をして、明日は続けます.