ES 6-エルゴード配列

10718 ワード

配列は重要なデータ構造である.行列はどうやって巡るのですか?配列中の要素をどうやって遍歴しますか?20年前にJavaScriptが生まれたばかりの時、あなたは配列をこのように実現するかもしれません.
for (var index = 0; index < myArray.length; index++) {
  console.log(myArray[index]);
}
ES 5が正式に発表されてから、内部建設のforEach方法を使って配列を巡回することができます.
myArray.forEach(function (value,index) {
console.log(index+":"+value);
});
このコードはより簡潔に見えるが、この方法にはbreak文を使ってサイクルを中断したり、return文を使って外層関数に戻すこともできない小さな欠陥がある.また、forEach方法はArayオブジェクトの方法であるので、DOMのクラス配列に対して、NodeListオブジェクトのようなものは遍歴できない.
もちろん、forループの文法だけで配列要素を遍歴するのもいいです.では、ぜひfor-iサイクルを試してみたいです.
for (var index in myArray) { //       
  console.log(myArray[index]);
}
これは絶対に悪い選択です.なぜですか?
  • は、このコードの中でindexに割り当てられた値は実際の数字ではなく、文字列「0」、「1」、「2」であり、このとき、無意識の間に文字列演算数計算を行う可能性が高く、例えば、「2」+1=「21」は、符号化過程に大きな不便をもたらす.
  • は配列のfor-i-n循環体として配列要素を巡回するだけでなく、カスタム属性を巡回します.例えば、あなたの配列にエニュメレーション属性のmyAray.nameがあれば、ループは追加的に実行され、「name」というインデックスを巡回します.配列のプロトタイプチェーン上の属性までアクセスできます.
  • の最も衝撃的なのは、いくつかの場合、このコードは、配列要素
  • をランダムな順序で巡回することができることである.
  • 簡単に言えば、for-innは通常のオブジェクトのために設計されており、文字列タイプのキーを巡回することができますので、配列遍歴
  • には適用されません.
    強力なfor-ofサイクル
    各エルゴード法を有するオブジェクトは、「巡回可能」オブジェクトと呼ばれる.for ofがデータセットを巡回した時、まずこのセットにエルゴード方法があるかどうかを探します.間違いがないなら、この方法を呼び出します.エルゴードメソッドは、オブジェクトを巡回する根本的な特徴は、nextメソッドです.nextメソッドを呼び出すたびに、現在のメンバーを表す情報オブジェクトが返されます.valueとdoneの2つの属性があります.
    for ofとは、常にnextメソッドを呼び出して遍歴するES 6規定であり、エルゴードメソッドは対象の「Symbol.iterator」属性に保存されています.
    let obj = {
        a:1,
        b:2
    };
    console.log(obj[Symbol.iterator]); //undefined
    for(let x of obj){
        console.log(x);   
    }
    // Uncaught TypeError: obj is not iterable
    オブジェクトはデフォルトのiteratorインターフェース([Symbol.iterator]がないので、for ofを巡回したときにエラーを投げました.このオブジェクトに[Symbol.iterator]属性を定義します.
    obj[Symbol.iterator]=function(){
        return {
            next: function(){
                return { value:1, done:false }
            }
        };
    }
    for(let x of obj){
        console.log(x);
    }
    エルゴード法があったら、for ofはこのオブジェクトを遍歴することができますが、done属性はfalseです.この遍歴は永遠に終わりません.
    オブジェクト(Object)がデフォルトで展開されていない理由は、オブジェクトのどの属性が先に巡回されているか、どの属性が巡回されているかは不明で、開発者が手動で指定する必要があるからです.実際には、エルゴードは線形処理であり、任意の非線形データ構造に対してエルゴードインターフェースを配置することは、線形変換の展開に等しい.しかし、厳密には、オブジェクト配置エルゴードインターフェースは必要ではない.この場合、オブジェクトは実際にMap構造として使用され、ES 5はMap構造を持っていない.
    [Symbol.iterator]属性を持つオブジェクトは、配列、いくつかの類似配列のオブジェクト、Set、Map構造です.私たちは対象の[Symbol.iterator]属性を自分で定義してデフォルトの[Symbol.iterator]属性をカバーできます.
    let arr=[1,2,3];
    arr[Symbol.iterator]=function(){
        let index=0;
        return {
            next:function(){
                if(indexreturn {
                        value:1,
                        done:false  
                    }
                }else{
                    return {
                        value:"    ",
                        done:true
                    }
                }
            }
        }
    };
     //  for of  
    let iterator = arr[Symbol.iterator]();
    iterator.next();    // {value: 1, done: false}
    iterator.next();    // {value: 1, done: false}  
    iterator.next();    // {value: 1, done: false}
    iterator.next();    // {value: "    ", done: true}
    
    for(let x of arr){
        console.log(x);  // 1 1 1
    }
    ES 6配列エルゴード方法
    ES 6は配列のプロトタイプにいくつかの新しいエルゴード配列方法を追加しました.Aray.prototype.entries()Aray.prototype.keys()とAray.prototype.values()
    for…of循環内部で呼び出したのは、データ構造のSymbol.iterator方法である.Aray.prototype.entries()Aray.prototype.keys()とAray.prototype.values()これらの方法は新しいSymbol.iterator方法に戻ります.for ofの内部で呼び出したのは新しい反復オブジェクトです.
    Aray.prototype.entries()の役割:配列を巡回するキーの値はパラメータに対して:戻り値がない:新しいAray Iteratorオブジェクトを返します.このオブジェクトは配列中の各インデックスのキー/値ペアを含みます.
    var arr = ["a", "b", "c"];
    var iterator = arr.entries();
    console.log(iterator);  // Array Iterator {}
    console.log(iterator.next());   // {value: [0, "a"], done:false}
    console.log(iterator.next()); // {value: [0, "a"], done:false}
    console.log(iterator.next()); // {value: [0, "a"], done:false}
    
    var iterator2 = arr.keys();
    console.log(iterator);  // Array Iterator {}
    console.log(iterator.next());   // {value: 0, done: false}
    console.log(iterator.next()); // {value: 1, done: false}
    console.log(iterator.next()); // {value: 2, done: false}
    
    //          
    for(let x of arr[Symbol.iterator]()){
            console.log(x);
    }
    
    // for of  arr.keys()       
    for(let x of arr.keys()){
        console.log(x);
    }
    
    // for of  arr.entries()       
    for(let [index,value] of arr.entries()){
        console.log(index,value);
    }
    
    console.log(arr.keys()===arr.entries());  //false
    arr.entries()は、配列内の各インデックスのキー値を含む新しいエルゴードオブジェクトを返します.配列内の各インデックスのキー値は、arr.keys()に対して返されます.
    拡張演算子(...)は、いくつかのデータ構造を行列に変換することもできます.
    [...[1,2,3]]    //[1,2,3]
    [...document.querySelectorAll('div')] // NodeList     Array  
    
    拡張演算子の背後で呼び出したのはエルゴードインターフェースです.オブジェクトがこのインターフェースを展開していないと、変換できません.拡張演算子は、オブジェクトのエルゴードメソッドを呼び出して、巡回します.
    let arr2=['a','b','c'];
    var iterator=arr2.entries();
    console.log([...iterator]);
    画像