如果在迭代期间添加基础集合,是否定义了数组迭代器的行为?

时间:2016-12-30 04:04:18

标签: javascript iterator generator

所以我有一种情况,我有一个生成器函数应该从数组返回值,但是数组正在消耗生成器输出的同一循环中填充。

特定方案是一个生成器,用于返回自动密钥密码的密钥序列,其中每个新解码的字符都附加到密码密钥的末尾。我的实现有效,但我不确定它是否有效,或者这是一个未定义行为的例子,恰好对我有利。

基本上,以下代码必须始终打印" a"," b"," c"," d",&#34 ; e"或者它是否适用于打印" a"," b"," c"," undefined&#34 ;,"未定义"?我总是对修改正在迭代的集合持怀疑态度。

let a = ["a", "b", "c"];
let iter = function*() { yield* a; }();
console.log(iter.next().value);  // "a"
console.log(iter.next().value);  // "b"
a.push("d");
a.push("e");
console.log(iter.next().value);  // "c"
console.log(iter.next().value);  // "d" - but is this guaranteed?
console.log(iter.next().value);  // "e" - or is it?

已修改:更改了标题,而不是谈论"生成器" to" iterators"更准确地反映问题的真正含义

1 个答案:

答案 0 :(得分:2)

根据 ES6&超越,来自Kyle Simpson,p。 103,yield *接受 iterable ,并“调用迭代的迭代器”。所以你真的在询问可迭代行为,而不是生成器行为。

我无法找到关于数组迭代器在修改底层数组时如何反应的官方规范,但我必须假设这样一个基本功能是正确实现的 - 也就是说,根据您的实验,新的数组元素包含在可迭代的。当然,除非你使用的是IE6。 : - )

因此,如果您希望您的生成器仅包含a[]的原始元素,则必须制作副本。 e.g。

let iter = function*(a) {
  let copy = Array.from(a);
  yield * copy;
}