所以我有一种情况,我有一个生成器函数应该从数组返回值,但是数组正在消耗生成器输出的同一循环中填充。
特定方案是一个生成器,用于返回自动密钥密码的密钥序列,其中每个新解码的字符都附加到密码密钥的末尾。我的实现有效,但我不确定它是否有效,或者这是一个未定义行为的例子,恰好对我有利。
基本上,以下代码必须始终打印" 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"更准确地反映问题的真正含义
答案 0 :(得分:2)
根据 ES6&超越,来自Kyle Simpson,p。 103,yield *
接受 iterable ,并“调用迭代的迭代器”。所以你真的在询问可迭代行为,而不是生成器行为。
我无法找到关于数组迭代器在修改底层数组时如何反应的官方规范,但我必须假设这样一个基本功能是正确实现的 - 也就是说,根据您的实验,新的数组元素包含在可迭代的。当然,除非你使用的是IE6。 : - )
因此,如果您希望您的生成器仅包含a[]
的原始元素,则必须制作副本。 e.g。
let iter = function*(a) {
let copy = Array.from(a);
yield * copy;
}