使用 for..of 循环遍历迭代器而不是 iterable 进行迭代是否合法?

Is iterating with for..of loop over iterator instead of iterable is legal?

迭代可迭代对象的推荐方法是使用 for..of 循环遍历对象本身,如下所示:

const a = [ 'one', 'two', 'three' ];
for(const item of a)
  console.log(item);

我一直在尝试迭代,发现以下方法也适用于完全相同的结果:

const a = [ 'one', 'two', 'three' ];
let iter = a[Symbol.iterator]();
for(const item of iter)
  console.log(item);

即使这样也行得通:

const a = [ 'one', 'two', 'three' ];
let iter = a[Symbol.iterator]();
let iter2 = iter[Symbol.iterator]();
for(const item of iter2)
  console.log(item);

关于 for..of 循环,我没有看到迭代 iterator 而不是 iterable 的建议。例如,参见 for..of in MDN.

这样迭代合法吗?

for..of 假设一个 Iterable(具有 Symbol.iterator 的东西)参见 https://262.ecma-international.org/11.0/#sec-runtime-semantics-forinofheadevaluation,第 7 点。

当您传递内置迭代器时,如 StringIteratorArrayIterator,没问题,因为对于内置迭代器(继承自 IteratorPrototypeSymbol.iterator 只是 returns 本身 (https://262.ecma-international.org/11.0/#sec-%iteratorprototype%-@@iterator).

不能保证用户定义的迭代器遵守此规则,但按此方式设计它们是一种很好的做法。