使用ES6制作​​迭代器

时间:2018-11-21 22:07:38

标签: javascript javascript-objects

这个问题有很多动态的部分,但是我将从我的第一个误解开始。

上下文:Iterator被定义为实现next()方法的对象,下面我的两个示例都具有这种方法。区别在于,我使用next()方法创建对象的方式有所不同。在第一个示例中,我正在创建一个函数,该函数返回包含next()方法的Object。然后,我为该函数分配一个变量,因此,如果我没有记错的话,我实际上是使用预定义的函数动态地制作一个对象。

var letters = ["a","b","c"];

function createIterator(array) {
    var i = 0;

    return {                //return an Object with a next() method
        next: function(){
            i < array.length ?    //if statement
            {value: array[i++], done: false}:
            {value: undefined, done: true};
         }
    }
}

var myIterator = createIterator(letters);
console.log(myIterator.next()) //{value: a, done: false}
console.log(myIterator.next()) //{value: b, done: false}
console.log(myIterator.next()) //{value: c, done: false}
console.log(myIterator.next()) //{value: undefined, done: true}

因此,通过将createIterator函数放入变量myIterator内,每次运行next()函数时,都会得到传递的数组中的下一个元素。

好的,我想。如果我只是使对象不具有功能怎么办?

var literal = {
    letters: ["a", "b", "c"],
    next: function(){        //same next function as before
        var i = 0;
        i < this.letters.length ? 
        {value: this.letters[i++], done: false}:
        {value: undefined, done: true};
         }
}

console.log(literal.next()) //{value: a, done: false}
console.log(literal.next()) //{value: a, done: false}
console.log(literal.next()) //{value: a, done: false}
console.log(literal.next()) //{value: a, done: false}

我认为这是由于我对如何使用不同的创建对象的方式调用next()方法的误解。可能有范围,但我真的不确定。

1 个答案:

答案 0 :(得分:1)

在第一个示例中,i被捕获在一个闭包中,因此可以正常工作。在第二个示例中,每次调用该函数时,i都会被创建。您可以将其设为对象的属性:

var literal = {
    letters: ["a", "b", "c"],
    i: 0,
    next: function(){        //same next function as before
       return this.i < this.letters.length ? 
        {value: this.letters[this.i++], done: false}:
        {value: undefined, done: true};
         }
}

console.log(literal.next()) 
console.log(literal.next()) 
console.log(literal.next()) 
console.log(literal.next()) 

当然,您也可以以在其他上下文中将其用作迭代器的方式来实现它,并且更为简单:

var G = {
    letters: ["a", "b", "c"],
    [Symbol.iterator]: function*(){      
       yield *this.letters
    }
}

// now the object works as an iterable:
console.log([...G])
// or
let iter = G[Symbol.iterator]()
console.log(iter.next()) 
console.log(iter.next()) 
console.log(iter.next()) 
console.log(iter.next())