我可以用一个简单的函数制作一个迭代器吗? (没有生成器或 Symbol.iterator)

Can I make an iterator with a simple function? (No generator or Symbol.iterator)

我一直在尝试使用普通函数制作迭代器,不使用生成器或出于学术目的使用 Symbol.iterator 协议。为此,我创建了一个函数 returns 一个带有 next 参数的对象,但试图 运行 它作为 for...of 循环的 iterable 参数产生不需要的结果。

到目前为止,这是我的代码,是我从 Iterators and Generators page on MDN:

复制的
function iterateThis(arr){
    let i = 0;
    return {
        next: function() {
            return i < arr.length ?
                {value: arr[i++], done: false} :
                {done: true};
        }
     };
}

如果我尝试 运行 它像这样:

const iterable = iterateThis([1,2,3,4,5]);
for(item in iterable){
    console.log(item);
}

在控制台上,我只得到一个结果:next

我是不是在创建函数时做错了什么iterateThis?或者 for...of 仅设计用于生成器和 Symbol.iterator 属性?

在节点 v8.11.1 上执行

问题是您的 iterateThis 函数 returns 是一个 迭代器 for/of 构造需要一个 iterable.

好的,等等,有什么区别?

来自 MDN's page on iteration protocols:

In order to be iterable, an object must implement the @@iterator method, meaning that the object (or one of the objects up its prototype chain) must have a property with a @@iterator key which is available via constant Symbol.iterator:

另一方面:

An object is an iterator when it implements a next() method with the following semantics: Ommited due to length, TL;DR: The next method returns an object of the form: {value: T, done: boolean}

它们的相关性在于调用 iterable returns 和 iterator@@iterator 方法。

for/of 循环总是需要一个可迭代的,所以如果你想使用 for/of,你必须使用 @@iterator/Symbol.iterator。据我所知,没有办法解决它。但是你的代码片段可以很容易地修改为使用它,只需创建一个对象,当它的 Symbol.iterator 方法被调用时 returns 你的迭代器:

function iterateThis(arr){
    let i = 0;
    return {
        next: function() {
            return i < arr.length ?
                {value: arr[i++], done: false} :
                {done: true};
        }
     };
}

function makeIterableFromIterator(iterator) {
  return {
    [Symbol.iterator]: function() {
      return iterator;
    }
  }
}

const iterator = iterateThis([1, 2, 3, 4, 5]);
const iterable = makeIterableFromIterator(iterator);

for (item of iterable) {
  console.log(item);
}