我正在从https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators了解有关Iterable的知识,并且清楚地指出Array是Iterable的。在chrome控制台中对其进行检查,我们可以看到它具有Symbol.iterator
,并且可以在其上运行for..of
。
但是数组似乎并不遵循具有next()
方法的迭代器模式,我很喜欢这种方法,因为您无法重置迭代器,这将严重限制数组。
但是我很难从文档中确定哪些Iterables具有完整的实现(next()),哪些没有,或者我在这里缺少基本概念。
我想念什么?
答案 0 :(得分:5)
我认为您缺少的是 iterator 与 iterable 有所不同。
数组是可迭代的,但不是迭代器。您可以从数组中获得一个迭代器,这使得它可以迭代:
// iterable
let arr = [1, 2, 3, 4]
// Symbol.iterator function returns the iterator
let it = arr[Symbol.iterator]()
// iterators have next()
console.log(it.next())
console.log(it.next())
console.log(it.next())
console.log(it.next())
console.log(it.next())
答案 1 :(得分:1)
马克·梅耶(Mark Meyer)的答案可帮助您了解可迭代和迭代器之间的关键区别。
如果要使自己的值可迭代,则必须实现Symbol.iterator
-
class Squares {
constructor (...values) {
this.values = values
}
*[ Symbol.iterator ] () {
for (const v of this.values)
yield v * v
}
}
const iterable =
new Squares(1, 2, 3, 4, 5)
for (const v of iterable)
console.log(v)
// 1
// 4
// 9
// 16
// 25
console.log(Array.from(iterable))
// [ 1, 4, 9, 16, 25 ]
现在看看如何从可迭代对象中获取迭代器-
class Squares {
constructor (...values) {
this.values = values
}
*[ Symbol.iterator ] () {
for (const v of this.values)
yield v * v
}
}
const iterable =
new Squares(1, 2, 3, 4, 5)
const iterator =
iterable[Symbol.iterator]()
console.log(iterator.next()) // { value: 1, done: false }
console.log(iterator.next()) // { value: 4, done: false }
console.log(iterator.next()) // { value: 9, done: false }
console.log(iterator.next()) // { value: 16, done: false }
console.log(iterator.next()) // { value: 25, done: false }
console.log(iterator.next()) // { value: undefined, done: true }