【发布时间】:2020-04-14 21:58:39
【问题描述】:
iterable 和 iterator 是一样的还是不同的?
看来,from the specifications,一个可迭代对象是一个对象,比如说,obj,这样obj[Symbol.iterator] 指的是一个函数,所以当被调用时,返回一个具有next 方法的对象,该方法可以返回{value: ___, done: ___} 对象:
function foo() {
let i = 0;
const wah = {
next: function() {
if (i <= 2) return { value: (1 + 2 * i++), done: false }
else return { value: undefined, done: true }
}
};
return wah; // wah is iterator
}
let bar = {} // bar is iterable
bar[Symbol.iterator] = foo;
console.log([...bar]); // [1, 3, 5]
for (a of bar) console.log(a); // 1 3 5 (in three lines)
所以在上面的代码中,bar 是可迭代对象,wah 是迭代器,next() 是迭代器接口。
所以,iterable 和 iterator 是不同的东西。
不过,现在来看一个生成器和迭代器的常见示例:
function* gen1() {
yield 1;
yield 3;
yield 5;
}
const iter1 = gen1();
console.log([...iter1]); // [1, 3, 5]
for (a of iter1) console.log(a); // nothing
const iter2 = gen1();
for (a of iter2) console.log(a); // 1 3 5 (in three lines)
console.log(iter1[Symbol.iterator]() === iter1); // true
在上面的例子中,gen1 是生成器,iter1 是迭代器,iter1.next() 将完成正确的工作。但是iter1[Symbol.iterator] 确实提供了一个函数,当调用该函数时,它会返回iter1,它是一个迭代器。那么iter1 在这种情况下既是可迭代的又是迭代器?
此外,iter1 与上面的示例 1 不同,因为示例 1 中的可迭代对象可以使用 [...bar] 任意多次给出 [1, 3, 5],而 iter1 是可迭代对象,但由于它返回自身,每次都是同一个迭代器,只会给[1, 3, 5]一次。
所以我们可以说,对于一个可迭代的bar,[...bar] 可以给出多少次结果[1, 3, 5]——答案是,这取决于。可迭代与迭代器一样吗?答案是,它们是不同的东西,但当可迭代对象将自己用作迭代器时,它们可以是相同的。对吗?
【问题讨论】:
-
"所以
iter1在这种情况下既是可迭代的又是迭代器?" - 是的。所有本机迭代器也可以通过返回自身来进行迭代,因此您可以轻松地将它们传递到期望可迭代的构造中。
标签: javascript ecmascript-6 iterator iterable