es6 迭代器_揭秘ES6迭代器和迭代器

es6 迭代器

by Tiago Lopes Ferreira

由Tiago Lopes Ferreira

揭秘ES6迭代器和迭代器 (Demystifying ES6 Iterables & Iterators)

ES6 introduces a new way to interact with JavaScript data structures — iteration. Let’s demystify it.

ES6引入了一种与JavaScript数据结构进行交互的新方法- 迭代 。 让我们揭开神秘面纱。

There are 2 core concepts:

有两个核心概念:

  • Iterable — described by a data structure that provides a way to expose its data to the public. This is done by implementing a method whose key is Symbol.iterator. Symbol.iterator is a factory of iterators.

    可迭代 -由数据结构描述,该数据结构提供了将其数据公开给公众的方式。 这是通过实现键为Symbol.iterator的方法来Symbol.iteratorSymbol.iterator是迭代器的工厂。

  • Iterator — described by a structure that contains a pointer to the next element in the iteration.

    迭代器 -由包含指向迭代中下一个元素的指针的结构描述。

协议 (Protocol)

Both iterable and iterator follow a protocol that enables objects to be iterable:

可迭代和迭代器均遵循使对象可迭代的协议:

  • An interable must be an object with a function iterator whose key is Symbol.iterator.

    一个互操作对象必须是带有函数迭代器的对象,该函数的键为Symbol.iterator

  • An iterator must be an object with a function named next that returns an object with the keys: value — the current item in the iteration; and donetrue if the iteration has finished, false otherwise.

    迭代器必须是具有next函数的对象,该函数返回具有以下键的对象: value —迭代中的当前项; 并done -如果迭代已完成,则为true ,否则为false

可重复性 (Iterability)

Iterability follows the idea of data sources and data consumers:

可迭代性遵循数据源数据使用者的思想:

  • data sources— are the place from where data consumers get their data. For instance, an Array such as [1,2,3] is a data source structure that holds the data through which a data consumer will iterate (e.g. 1, 2, and 3). More examples are String, Maps and Sets.

    数据源 -是数据使用者从中获取数据的地方。 例如,诸如[1,2,3]类的Array是一种数据源结构,其中保存数据,数据使用者将通过该数据进行迭代(例如1, 2, and 3 )。 更多示例包括StringMapsSets

  • data consumers — are the what consume the data from data sources. For instance, the for-of loop is a data consumer able to iterate over an Array data source. More examples are the spread operator and Array.from.

    数据使用者 -消耗数据源中数据的对象。 例如, for-of循环是一个能够遍历Array数据源的数据使用者。 spread operatorArray.from是更多示例。

For a structure to be a data source, it needs to allow and say how its data should be consumed. This is done through iterators. Therefore, a data source needs to follow the iterator protocol described above.

为了使结构成为数据源 ,它需要允许并说出应如何使用其数据。 这是通过迭代器完成的。 因此, 数据源需要遵循上述迭代器协议。

However, it’s not practical for every data consumer to support all data sources, especially since JavaScript allows us to build our own data sources. So ES6 introduces the interface Iterable.

但是,每个数据使用者都不支持所有数据源是不切实际的,特别是因为JavaScript允许我们构建自己的数据源。 因此,ES6引入了Iterable接口

Data consumers consume the data from data sources through iterables.

数据使用者通过可迭代对象消耗数据源中的数据。

在实践中 (In Practice)

Let’s see how this works on a defined data source — Array.

让我们看看如何在定义的数据源Array

可迭代的数据源 (Iterable Data Sources)

We will use for-of to explore some of the data sources that implement the iterable protocol.

我们将使用for-of探索实现可迭代协议的一些数据源。

普通物体 (Plain Objects)

At this stage we need to say that plain objects are not iterable. Axel Rauschmayer does a great job explaining why on Exploring ES6.

在这一阶段,我们需要说普通对象是不可迭代的。 Axel Rauschmayer出色地解释了为什么要探索ES6

A brief explanation is that we can iterate over a JavaScript objects at two different levels:

一个简短的解释是,我们可以在两个不同的级别上遍历一个JavaScript对象:

  • program level — which means iterating over an object properties that represent it’s structure. For instance, Array.prototype.length, where length is related with the object’s structure and not it’s data.

    程序级别 –意味着遍历代表其结构的对象属性。 例如, Array.prototype.length ,其中length与对象的结构而不是数据有关。

  • data level — meaning iterating over a data structure and extracting its data. For instance, for our Array example, that would mean iterating over the array’s data. If array = [1,2,3,4], iterate over the values 1, 2, 3 and 4.

    数据级别 -意味着遍历数据结构并提取其数据。 例如,对于我们的Array示例,这意味着迭代数组的数据。 如果array = [1,2,3,4] ,则迭代值1, 2, 3 and 4

However, bringing the concept of iteration into plain objects means mixing-up program and data structures Axel

但是,将迭代的概念引入普通对象意味着混合程序和数据结构 -Axel

The problem with plain objects is everyones’ ability to create their own objects.

普通对象的问题是每个人都可以创建自己的对象。

In our Hugo’s example how would JavaScript distinguish between the data level, i.e. Hugo.fullName, and the program level, i.e. Hugo.toString()?

在我们的Hugo例子中,JavaScript如何区分数据级别(即Hugo.fullName )和程序级别(即Hugo.toString()

While it is possible to distinguish between the two levels of iteration on well-defined structures, such as Arrays, it is impossible to do so for any object.

虽然可以在定义良好的结构(例如Arrays上区分两个迭代级别,但是对于任何对象都不可能做到这一点。

This is why we get iteration for free on Array (also on String, Map, and Set) but not on plain objects.

这就是为什么我们可以在Array (在StringMapSet )免费获得迭代,而在普通对象上不能免费获得迭代的原因。

We can, however, implement our own iterables.

但是,我们可以实现自己的可迭代对象。

实施可迭代 (Implement Iterables)

We can build our own iterables, although we usually use generators for that.

尽管我们通常为此使用生成器,但我们可以构建自己的可迭代对象。

In order to build our own iterable we need to follow the iteration protocol, which says:

为了构建自己的可迭代对象,我们需要遵循迭代协议,该协议指出:

  • An object becomes an iterable if it implements a function whose key is Symbol.iterator and returns an iterator.

    如果对象实现了键为Symbol.iterator的函数并返回iterator则该对象成为 iterator

  • The iterator itself is an object with a function called next inside it. next should return an object with two keys value and done. value contains the next element of the iteration and done a flag saying if the iteration has finished.

    iterator本身是一个对象,该对象内部具有一个称为next的函数。 next应该有两个键返回一个对象valuedonevalue包含迭代的下一个元素,并done了一个标志,指出迭代是否已完成。

(Example)

Our iterable implementation is very simple. We have followed the iterable protocol and on each iteration the for-of loop will ask the iterator for the next element.

我们的迭代实现非常简单。 我们遵循了可迭代的协议,并且在每次迭代中, for-of循环都会向迭代器询问next元素。

Our iterator will return on next an object containing the following by iteration:

next ,我们的迭代器将通过迭代返回一个包含以下内容的对象:

Please note that we switch the order of the our properties next and done for convenience. Having next first, it would break the implementation since we will first pop an element and then count the elements.

请注意,为了方便起见,我们next切换属性的顺序并done 。 首先拥有next一个,这将破坏实现,因为我们将首先弹出一个元素,然后对元素进行计数。

It is useful to know that done is false by default, which means that we can ignore it when that’s the case. The same is true for value when done is true.

知道默认情况下donefalse的,这很有用,这意味着在这种情况下我们可以忽略它。 当donetrue时, value也是true

We will see that in a minute.

我们将在一分钟内看到。

作为迭代器的迭代器 (Iterator as an Iterable)

We could build our iterator as an iterable.

我们可以将迭代器构建为可迭代的。

Please note that this is the pattern followed by ES6 built-in iterators.

请注意,这是ES6内置迭代器遵循的模式。

Why is this a useful?

为什么这很有用?

Although for-of only works with iterables, not with iterators, being the same means that we can pause the execution of for-of and continue afterwords.

尽管for-of仅适用于可迭代对象,不适用于迭代器,但相同意味着我们可以暂停for-of的执行并继续执行后记。

回程和掷球 (Return and Throw)

There are two optional iterator methods that we haven’t explore yet:

我们还没有探讨两种可选的迭代器方法:

Return

返回

return gives the iterator the opportunity to clean up the house when it breaks unexpectedly. When we call return on an iterator we are specifying that we don’t plan to call next anymore.

return给迭代器一个机会,当它意外崩溃时,它可以清理房子。 当我们在迭代器上调用return时,我们指定不打算再调用next了。

Throw

throw is only applied to generators. We will see that when we play with generators.

throw仅应用于生成器。 当我们使用生成器时,我们会看到这一点。

结论 (Conclusion)

ES6 brings iteration as a new way to iterate over JavaScript data structures.

ES6将迭代作为迭代JavaScript数据结构的新方法。

For iteration to be possible there are data producers, who contain the data, and data consumers, who take that data.

为了使迭代成为可能,需要有包含数据的数据生产者和获取数据的数据使用者

In order for this combination to work smoothly iteration is defined by a protocol, which says:

为了使此组合顺利运行,协议定义了迭代,该协议表示:

  • An iterable is an object that implements a function whose key is Symbol.iterator and returns an iterator.

    一个iterable是一个对象,该对象实现一个键为Symbol.iterator并返回iterator

  • An iterator is an object with a function called next inside it. next is an object with two keys value and done. value contains the next element of the iteration and done a flag saying if the iteration has finished.

    iterator是一个对象,其内部具有一个称为next的函数。 next是两个键对象valuedonevalue包含迭代的下一个元素,并done了一个标志,指出迭代是否已完成。

Plain objects are not iterable since there’s no easy way to distinguish between program and data level iteration.

普通对象是不可iterable因为没有简单的方法可以区分程序和数据级别的迭代。

That’s why ES6 offers a way to build our own iterators by following the iterator protocol.

这就是为什么ES6提供一种通过遵循iterator协议来构建自己的迭代iterator

谢谢 ? (Thanks to ?)

Be sure to check out my other articles on ES6

请务必查看我有关ES6的其他文章

Let’s explore ES6 GeneratorsGenerators are an implementation of iterables.medium.freecodecamp.com

让我们探索一下ES6生成 生成 器是可迭代的实现。 medium.freecodecamp.com

翻译自: https://www.freecodecamp.org/news/demystifying-es6-iterables-iterators-4bdd0b084082/

es6 迭代器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值