1. 程式人生 > >ES6入門——Iterator和for...of迴圈

ES6入門——Iterator和for...of迴圈

Iterator(遍歷器)

遍歷器(Iterator)是一種協議,任何物件只要部署了這個協議,就可以完成遍歷操作。在ES6中遍歷操作特質for….of迴圈。

它的作用主要有兩個:

  1. 為遍歷物件的屬性提供統一的介面。
  2. 使物件的屬效能夠按次序排列。

ES6的遍歷器協議規定,部署了next方法的物件,就具備了遍歷器功能。next方法必須返回一個包含value和done兩個屬性的物件。value屬性是當前遍歷的位置的值,而done屬性是一個布林值,用來表示遍歷是否結束。

    function makeIterator(array) {
        var nextIndex = 0
; return { next: function() { return nextIndex < array.length ? {value: array[nextIndex++], done: false} : {value: undefined, done: true}; } } } var it = makeIterator(['a', 'b']); it.next
().value; //'a' it.next().value; //'b' it.next().done; // true

在上面程式碼片段中,定義了一個makeIterator函式,它的作用是返回一個遍歷器物件,用來遍歷引數陣列。特別需要注意的是next返回值的構造。

下面,再看看一個遍歷器的示例程式碼片段:

    function idMaker() {
        var index = 0;
         return {
            next: function() {
                return {value: index++, done: false
}; } } } var it = idMaker(); it.next().value; //'0' it.next().value; //'1' it.next().value; //'2'

for…of 迴圈

在ES6中,一個物件只要部署了next方法,就被視為是具有了iterator介面,就可以用for…of迴圈遍歷它的值。

    function idMaker() {
        var index = 0;
        return {
            next: function() {
                return {value: index++, done: false};
            }
        }
    }

    for (var n of it) {
        if (n > 5) {
            break;
            console.log( n );
        }
    }
    //0
    //1
    //2
    //3
    //4
    //5

上面的程式碼說明,for….of預設從0開始迴圈。

陣列原生具備iterator介面

    const arr = [1, 5, 3, 9];
    for (let v of arr) {
        console.log( v );
    }
    //1
    //5
    //3
    //9

相比較,Js原有的for…in迴圈,只能獲得物件的鍵名,不能直接獲取鍵值。ES6提供了for…of迴圈,允許遍歷獲取鍵值。

    var arr = ['a', 'b', 'c', 'd'];

    for (a in arr) {
        console.log( a );
    }
    //0
    //1
    //2
    //3

    for (a of arr) {
        console.log( a );
    }
    //0
    //1
    //2
    //3

上面的程式碼片段表明,for…in迴圈讀取鍵名,而for…of迴圈讀取鍵值。

對於Set和Map結構的資料,可以直接使用for…of迴圈。

    var name = ['S', 'D', 'J', 'Z', 'G', 'G', 'G'];
    for ( var e of name) {
        console.log( e );
    }
    //S
    //D
    //J
    //Z
    //G


    var es6 = new Map();
    es6.set('edition', 6);
    es6.set('committee', 'TC39');
    es6.set('standard', 'ECMA-262');
    for(var [name, value] of es6) {
         console.log(name + ": " + value);
    }
    // edition: 6
    // commttee: TC39
    // standard: ECMA-262

在上面的程式碼片段中,演示瞭如何遍歷Set結構和Map結構,後者是同是遍歷鍵名和鍵值。

對於普通的物件,for...of結構不能直接使用,否則則會報錯。必須項部署iterator介面才能使用。但是,在這種情況下,for...in迴圈依然可以遍歷鍵名。

    var es6 = {
        name: "G.Dragon",
        year: 22,
        love: "coding"
    };

    for (e in es6) {
        console.log( e );
    }
    //name
    //year
    //love

    for( e of es6) {
        console.log( e );
    }
    // TypeError: es6 is not iterable

最後,總結一下。for...of迴圈可以使用的範圍包括陣列、類似陣列的而物件(比如argument物件、DOM NodeList物件)、Set和Map結構、後文的Generator物件,以及字串。下面是使用for...of迴圈遍歷字串和DOM NodeList物件的例子。

    // 字串例子
    let str = "hello";

    for (let s of str) {
        console.log( s );
    }
    //h
    //e
    //l
    //l
    //o

    // DOM NodeList物件的例子
    let paras = document.getSelectorAll("p");
    for (let p of paras) {
        p.classList.add("test");
    }