所有JavaScript可迭代对象是否都具有next()方法?

时间:2019-05-15 15:37:44

标签: javascript arrays iterator iterable

我正在从https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators了解有关Iterable的知识,并且清楚地指出Array是Iterable的。在chrome控制台中对其进行检查,我们可以看到它具有Symbol.iterator,并且可以在其上运行for..of

但是数组似乎并不遵循具有next()方法的迭代器模式,我很喜欢这种方法,因为您无法重置迭代器,这将严重限制数组。

但是我很难从文档中确定哪些Iterables具有完整的实现(next()),哪些没有,或者我在这里缺少基本概念。

我想念什么?

2 个答案:

答案 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 }