无法对使用*[Symbol.iterator]()生成器javascript创建的iterable对象使用next()

无法对使用*[Symbol.iterator]()生成器javascript创建的iterable对象使用next(),javascript,generator,next,Javascript,Generator,Next,我试着用谷歌搜索这个问题,并仔细研究类似的问题,但我似乎遗漏了一些基本的东西 let collection = { items: [], *[Symbol.iterator]() { for (let item of this.items) { yield item; } } } collection.items.push(1); collection.items.push(2); console.log(colle

我试着用谷歌搜索这个问题,并仔细研究类似的问题,但我似乎遗漏了一些基本的东西

let collection = {
    items: [],
    *[Symbol.iterator]() {
        for (let item of this.items) {
            yield item;
        }
    }
}
collection.items.push(1);
collection.items.push(2);
console.log(collection.next()); 
这会抛出一个错误

console.log(collection.next());
                       ^

TypeError: collection.next is not a function 

据我所知,我应该能够在集合对象上使用next(),因为这将调用Symbol.iterator属性?

实际上有两种不同的协议

  • “Iterable”-这是我使用
    *[Symbol.iterator]()
    生成器实现的。这允许…的循环等

  • “迭代器”-这意味着在对象上定义下一个方法
引用文件:

创建同时满足迭代器和iterable协议的对象很容易(如下例所示)。 这样做允许迭代器被各种语法所使用。因此,在不实现Iterable的情况下实现迭代器协议很少有用

因此,我重写了我的代码,如下所示:

let collection = {
    items: [],
    *[Symbol.iterator]() {
        for (let item of this.items) {
            yield item;
        }
    },
    i: 0,
    next: function() {
        let done = (this.i >= this.items.length);
        let value = !done ? this.items[this.i++] : undefined
        return {
            done,
            value
        }
    }
}
collection.items.push(1);
collection.items.push(2);
for (let i of collection) console.log(i); // demonstrates the iterable protocol
console.log(collection.next()); // demonstrates the iterator protocol
console.log(collection.next());
console.log(collection.next());

最后要注意的是,这不是私有对象,应该包装在类中或立即调用函数,以避免任何其他代码等访问这些属性。

您需要调用
[Symbol.iterator]()
方法来获取迭代器对象,然后对返回的对象调用
next()
方法:

let集合={
项目:[],
*[符号.迭代器](){
对于(让此.items中的项目){
收益项目;
}
}
};
集合。项目。推送(1);
收集。物品。推送(2);
让迭代器=集合[Symbol.iterator]();
log(iterator.next());
log(iterator.next());

log(iterator.next())否,
.next()
位于从第一次调用返回的对象上。尝试在
中使用您的对象以。。。属于
数组.from()
或类似的东西。
用于(让我来收集)控制台.log(我)返回我压入items数组属性的两个数字。这很好,这只是下一个不起作用的方法。我知道“array”已经是任何一个iterable了。我试图创建一个新的集合对象,它具有可以定制的奇异属性。这可能相当神秘。然而,我认为我的想法是,一个新的iterable对象可能不应该以单例方式创建
next
方法,而是应该每次创建一个迭代器,这样我们就可以同时运行多个迭代器。@lindsaymacvean是的。同一个对象应该实现这两者的唯一时间是,如果您的迭代器对象引用自身以方便地用作iterable,例如,
let iterator={[Symbol.iterator](){return this;},next(){/*一些非平凡的实现*/}