1. 首页

Javascript ES6 Iterators建议指南(含实例)

由Arfat Salman发布

Javascript ES6 Iterators建议指南(含实例)

本文旨在分析理解 IteratorsIterators 是 JavaScript 中的新方法,可以用来循环任意集合。 在ES6中登场的Iterators。因其可被广泛使用,并且已在多处场景派上用场,现已十分流行。

我们从概念上去理解iterators,通过实例讲述在何处使用。并且. We’ll also see some of its implementations in JavaScript.

介绍

Js中文网 – 前端进阶资源教程 www.javascriptC.com,typescript 中文文档
一个帮助开发者成长的社区,你想要的,在这里都能找到

如果你有下面的数组 ——


const myFavouriteAuthors = [ 'Neal Stephenson', 'Arthur Clarke', 'Isaac Asimov', 'Robert Heinlein' ];

有时,你需要获取这个数组中每一个值,在屏幕上显示它们,操作它们,或者依据它们做些事情。如果我问你将如何处理?你会说,这很简单——我循环它们就是了,可以用for__, while__, for-of 或者这些循环方法中的任意一个。

Javascript ES6 Iterators建议指南(含实例)各种循环数组的方法

如果现在不是前面的数组,而是以自定的数据结构保存所有的authors,比如——

Javascript ES6 Iterators建议指南(含实例) 自定数据结构

现在, myFavouriteAuthors 是一个包含了对象 allAuthors 的对象,allAuthors包含了三个数组,对应key值为fiction, scienceFiction,和 fantasy现在如果需要遍历myFavouriteAuthors 来获取所有的作者, 你的方法是什么?你可以继续尝试一些循环组合来获取所有数据。

然而,如果你这样做 —


for (let author of myFavouriteAuthors) { console.log(author) } // TypeError: {} is not iterable

你会得到一个该对象不是_可迭代的_TypeError。 我们来看看迭代是什么,以及我们如何使对象可迭代。在本文的最后,你将知道如何在这种情况下,在myFavouriteAuthors上,在自定义对象上使用for-of循环。

Iterables(可迭代对象) and Iterators(迭代器)

在上一节中看到了问题所在。 没有方法可以简单得从我们的自定义对象中获取所有作者。 我们想要一种方法,通过它我们可以有序地呈现所有内部数据。

让我们在myFavouriteAuthors中添加一个返回所有作者的方法getAllAuthors。 像这样 ——

Javascript ES6 Iterators建议指南(含实例) getAllAuthors 的实现

这是一个简单的方法。 它完成了获得所有作者的当下目标。 但是,这种实现可能会出现一些问题。 比如——

  • getAllAuthors这个名字非常具体。 如果其他人正在创建他们自己的myFavouriteAuthors,他们可能会将其命名为retrieveAllAuthors

  • 作为开发人员,我们始终需要了解将返回所有数据的特定方法。 在这个案例里,它被命名为getAllAuthors

  • getAllAuthors返回包含所有作者的字符串数组。 如果另一个开发人员以这种格式返回一个对象数组会怎样——


[ {name: 'Agatha Christie'}, {name: 'J. K. Rowling'}, ... ]

Js中文网 – 前端进阶资源教程 www.javascriptC.com,typescript 中文文档
一个帮助开发者成长的社区,你想要的,在这里都能找到

开发人员必须知道,返回所有数据的方法的确切名称和返回类型

如果我们制定一个规则,该方法的名称及其返回类型是固定且不可更改的,这怎么办?

让我们将这个方法命名为——iteratorMethod.

ECMA采取了类似的步骤,来标准化循环自定义对象的过程。但是,ECMA使用Symbol.iterator而不是iteratorMethodSymbols提供唯一且不能与其他属性名称冲突的名称。 此外,Symbol.iterator将返回一个名为iterator的对象。 这个迭代器将有一个名为next的方法,它将返回一个包含key为valuedone对象,

keyvalue中将包含当前值。 它可以是任何类型。 done是布尔值。 它表示是否已获取所有值。

下图可能有助于建立 _ iterables __ iterators __ next _ 之间的关系。 这种关系称为迭代协议。

Javascript ES6 Iterators建议指南(含实例) iterables, iterators, 和 next之间的关系。

参考Axel Rauschmayer博士Exploring JS 一书 —

  • _ iterable _ 是一种数据结构,旨在使其元素可在公用环境被访问。 它通过实现一个key为Symbol.iterator的方法来实现。 该方法是 iterators 的工厂。 也就是说,它将创建 iterators .

  • iterator 是用于遍历数据结构中元素的指针。

使对象可迭代

正如我们在上一节中所学到的,我们需要实现一个名为Symbol.iterator的方法。我们将使用 computed property syntax 来设置这个key。举一个简短的例子 —

Javascript ES6 Iterators建议指南(含实例) 可迭代的示例

在第4行,我们创建iterator。 这是一个定义了next方法的对象。 next方法根据step变量返回对应的值。 在第25行,我们取到iterator。 27行,我们调用next方法。 接下来我们继续调用,直到done变成’true`。

这正是for-of循环中发生的事情。 for-of循环采用 iterable ,并为其创建_ iterator_ 。 不断调用next()直到done为真。

JavaScript中的 Iterables

很多东西在JavaScript中都是可迭代的。 它可能不是立等可见的,但如果仔细观察,是能看到iterables的。

这些都是可迭代的 ——

  • Arrays and TypedArrays

  • Strings —迭代每个字符或 Unicode code-points.

  • Maps —迭代 key-value 组合

  • Sets —迭代它们的元素

  • arguments — 函数中一个类似数组的特殊变量

  • DOM 元素 (实现中)

其他在JS中使用iterables的 ——

  • for-of 循环 — for-of循环需要迭代。 否则,它将抛出一个TypeError.

for (const value of iterable) { ... }
  • 数组的解构 ——由于可迭代而发生解构。 我们来看看如何实现。

代码:


const array = ['a', 'b', 'c', 'd', 'e']; const [first, ,third, ,last] = array;

相当于


const array = ['a', 'b', 'c', 'd', 'e']; const iterator = array[Symbol.iterator](); const first = iterator.next().value iterator.next().value // Since it was skipped, so it's not assigned const third = iterator.next().value iterator.next().value // Since it was skipped, so it's not assigned const last = iterator.next().value
  • 延展符 (…)

代码:


const array = ['a', 'b', 'c', 'd', 'e']; const newArray = [1, ...array, 2, 3];

可以写成


const array = ['a', 'b', 'c', 'd', 'e']; const iterator = array[Symbol.iterator](); const newArray = [1]; for (let nextValue = iterator.next();nextValue.done !== true;nextValue = iterator.next()) { newArray.push(nextValue.value); } newArray.push(2) newArray.push(3)
  • Promise.allPromise.race 接受Promises上的迭代。

  • Maps and Sets

Map的构造函数将[key,value]形式的迭代器转换为Map,Set的构造函数将可迭代的元素转换为Set——


const map = new Map([[1, 'one'], [2, 'two']]); map.get(1) // one const set = new Set(['a', 'b', 'c]); set.has('c'); // true
  • 要理解generator 函数,先理解迭代器。

让myFavouriteAuthors可迭代

这是一个使myFavouriteAuthors可迭代的实现方式。

可迭代的实现示例

根据本文的介绍,您可以轻松了解迭代器的工作方式。 可能有点难以理解它的逻辑,所以,我已经为代码写了注释。 但是,吸收和理解概念的最佳方法是让这些代码在浏览器或node中运行起来。

如有疑问,欢迎回复! 参考:

看完两件小事

如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:

  1. 关注我们的 GitHub 博客,让我们成为长期关系
  2. 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
  3. 关注公众号 「画漫画的程序员」,公众号后台回复「资源」 免费领取我精心整理的前端进阶资源教程

JS中文网是中国领先的新一代开发者社区和专业的技术媒体,一个帮助开发者成长的社区,目前已经覆盖和服务了超过 300 万开发者,你每天都可以在这里找到技术世界的头条内容。欢迎热爱技术的你一起加入交流与学习,JS中文网的使命是帮助开发者用代码改变世界

本文来源于网络,其版权属原作者所有,如有侵权,请与小编联系,谢谢!

转载请注明:文章转载自「 Js中文网 · 前端进阶资源教程 」https://www.javascriptc.com

标题:Javascript ES6 Iterators建议指南(含实例)

链接:https://www.javascriptc.com/1954.html

原文链接:https://www.zcfy.cc/article/a-simple-guide-to-es6-iterators-in-javascript-with-examples

« 你是否头疼于,每天做不完的需求和改不完的bug?
玩转CSS 与 JS 动画的底层机制 之 如何优化它们的性能篇»
Flutter 中文教程资源

相关推荐

QR code