JavaScript 中的迭代器和迭代器介绍

JavaScript 支持通过数据集对象循环,例如使用控制结构的数组,如 for...of和扩散操作员 .... 这被称为可迭代,支持此功能的数据结构被称为可迭代。

Iterables 是提供一个机制的数据结构,允许其他数据用户以连续的方式公开访问其元素。

可迭代协议的概念可以被分为可迭代协议,数据结构本身,和迭代器,一个向导器移动的迭代器. 考虑一个数组,例如. 当数组被用在一个为...of循环,可迭代属性被称为返回一个iterator。 这个可迭代属性被命名为Symbol.iterator,它返回的对象可以在一个共同的界面上使用,这是所有循环控制结构共享的。

在某种程度上,Symbol.iterator可以与一个迭代器工厂相比,每当数据结构被放置在循环中时,它会产生一个迭代器。

JavaScript iterable

随着迭代器在数据结构上移动并连续提供元素,由迭代器返回的对象包含一个和一个完成属性。

JavaScript iterator

该值表示 iterator 指定的当前数据值,完成是一个 boolean 值,它告诉我们 iterator 是否已到达数据结构中的最后一个元素。

{值,完成} 被结构如循环所消耗,以便迭代器方法调用下一个对象,一个在 Symbol.iterator() 方法中定义的 next() 方法。

换句话说,迭代器属性可以定义为知道如何从集合中访问元素的属性,它还包含停止逻辑,例如当数组中不再有元素时。

了解对象和 iterables

默认情况下,JavaScript 对象不包含可重复性,这里有一些潜在的合理性:

  • 对象的关键特征之一是它是用户定义的,所以在对象中沉默地滑动 [Symbol.iterator]() 可能会导致意想不到的行为.
  • 前一个点也意味着它可以由用户手动添加,考虑到所有对象组成可能并不相似。

如果您仍然需要一个可迭代的,对象上的简单可迭代的实现将看起来像这样:

 1let Reptiles = {
 2  biomes: {
 3    water: ["Alligators", "Crocs"],
 4    land: ["Snakes", "Turtles"]
 5  },
 6
 7  [Symbol.iterator]() {
 8    let reptilesByBiome = Object.values(this.biomes);
 9    let reptileIndex = 0;
10    let biomeIndex = 0;
11    return {
12      next() {
13        if (reptileIndex >= reptilesByBiome[biomeIndex].length) {
14          biomeIndex++;
15          reptileIndex = 0;
16        }
17
18        if (biomeIndex >= reptilesByBiome.length) {
19          return { value: undefined, done: true };
20        }
21
22        return {
23          value: reptilesByBiome[biomeIndex][reptileIndex++],
24          done: false
25        };
26      }
27    };
28  }
29};
30
31// now iterate over the new `Reptiles` iterable:
32for (let reptile of Reptiles) console.log(reptile);

产量将是:

1Alligators
2Crocs
3Snakes
4Turtles

使用此示例,您可以看到可在对象中实现迭代器。Iterables 可以为对象提供强大的属性,在处理某些情况时提供易用性,并帮助我们避免写长路径名称。

进入Iterator

像「for...of」这样的循环具有内置机制来消耗迭代,直到「完成」值被评估为 true. 如果您想自行消耗迭代,但没有内置循环,您可以从迭代器中获取迭代器,然后手动拨打 next()。

考虑到与上面的相同的例子,你可以通过这样称呼它的Symbol.iterator来获得从爬行动物的迭代器:

1let reptileIterator = Reptiles[Symbol.iterator]();

您可以这样使用 iterator:

 1console.log(reptileIterator.next());
 2// {value: "Alligators", done: false}
 3console.log(reptileIterator.next());
 4// {value: "Crocs", done: false}
 5console.log(reptileIterator.next());
 6// {value: "Snakes", done: false}
 7console.log(reptileIterator.next());
 8// {value: "Turtles", done: false}
 9console.log(reptileIterator.next());
10// {value: undefined, done: true}
11
12console.log(reptileIterator.next());
13// TypeError: Cannot read property 'length' of undefined

正如你所看到的,迭代器有一个next()方法,它会返回迭代器中的下一个值。为完成的值仅在最后一个值被返回后评估为,因此要通过整个迭代器,总会有一次再调用next(),而不是迭代器中的数据。在迭代器到达迭代器的尽头之后,再次调用next()会导致TypeError被扔掉。

结论

通过本教程,您已经通过了通过JavaScript数据集循环背后的不同部分和机制,您已经通过了JavaScript对象不具有这种天生的迭代能力的原因,并展示了手动实现自己的迭代的可能性。

Published At
Categories with 技术
Tagged with
comments powered by Disqus