You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
为了保证的可读性,本文采用意译而非直译。
本文旨在分析理解 Iterators。 Iterators 是 JS中的新方法,可以用来循环任意集合。 在ES6中登场的Iterators。因其可被广泛使用,并且已在多处场景派上用场,
我们将从概念上理解迭代器是什么,以及在何处使用它们和示例。我们还将看到它在JS 中的一些实现。
简介
假设有这样数组
在某些情况下,希望返回数组中的所有单独值,以便在屏幕上打印它们、操作它们或对它们执行某些操作。
如何处理? 简单方法就是使用
for
,while
,for-of
方法。如下:
现在,假设你拥有一个自定义数据结构来保存所有
authors
myFavouriteAuthors
是一个对象,它包含另一个对象allAuthors
。allAuthors
包含三个数组,其中包含fiction
、scienceFiction
和fantasy
。现在,如果要求你循环遍历
myFavouriteAuthors
以获得所有的author
,你的方法是什么? 你可能会尝试一些循环组合来获得所有数据。但是,如果你这样做了 ——
你将得到一个类型错误,说明该对象不可迭代。让我们看看什么是可迭代的,以及如何使对象可迭代。
可迭代对象与迭代器 (Iterables and Iterators)
在上一节中看到了问题,从我们的自定义对象中获取所有的
author
是不容易的。我们需要某种方法,通过它我们可以有序地获取内部数据。我们在
myFavouriteAuthors
中添加一个返回所有作者的方法getAllAuthors
。如:这是一个简单的方法。它帮我们完成了获取所有
author
的功能。但是,这种实现可能会出现一些问题:getAllAuthors
的名称非常具体。如果其他人正在创建自己的myFavouriteAuthors
,他们可能会将其命名为retrieveAllAuthors
。作为开发人员,我们总是需要知道返回所有数据的特定方法,在本例中,它被命名为
getAllAuthors
。getAllAuthors
返回的是字符串数组,如果另一个开发人员以这种格式返回一个对象数组,该怎么办:[ {name: 'Agatha Christie'}, {name: 'J. K. Rowling'}, ... ]
开发人员必须知道返回所有数据的方法的确切名称和返回类型。
如果我们规定方法的名称和它的返回类型是固定不变的呢?
让我们将这个方法命名为 --- iteratorMethod
ECMA 也采取了类似的步骤来标准化在定制对象上循环的过程。但是,ECMA 没有使用名称
iteratorMethod
,而是使用名称 Symbol.iterator。Symbols 提供的名称是唯一的,不能与其他属性名称冲突。同时,Symbol.iterator 返回一个名为迭代器的对象,这个迭代器将拥有一个名为
next
的方法,该方法将返回一个具有键值为value
和done
的对象。值键
value
包含当前值,它可以是任何类型的,done
是布尔值,它表示是否获取了所有的值。下图可以帮助建立可迭代对象、迭代器和
next
之间的关系,这种关系称为迭代协议。根据Axel Rauschmayer博士的《探索JS》一书:
可迭代是一种数据结构,它希望使其元素对外部可访问,通过实现一个关键字是
Symbol.iterator
的方法来实现,该方法是迭代器的工厂,也就是说,它将创建迭代器。迭代器是一个指针,用于遍历数据结构的元素,我们将使用computed property语法来设置这个键,如下:
使用对象可迭代
因此,正如我们在上一节学到的,我们需要实现一个名为
Symbol.iterator
的方法在第4行,我们创建迭代器。它是一个定义了
next
方法的对象。next
方法根据step
变量返回值。在第25行,我们检索iterator
,27 行,我们调用next
方法,直到done
的值为 true。这正是
for-of
循环中发生的事情,for-of
接受一个迭代器,并创建它的迭代器,它会一直调用next(),直到done
为 true。JavaScript中可迭代对象(iterable)
JS 中的很多对象都是可迭代的。它们可能不是很好的察觉,但是如果仔细检查,就会发现迭代的特征:
arguments
—— 函数中类似数组的特殊变量JS中使用迭代的其他一些结构是:
for-of
-- for-of 循环需要一个可迭代的对象,否则,它将抛出一个类型错误。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 newArray = [1, ...array, 2, 3];
等价于:
Promise.all
和Promise.race
接受可迭代对象Maps 和 Sets
让 myFavouriteAuthors 可迭代
下面是一个实现,它使
myFavouriteAuthors
具有可迭代性:通过本文获得的知识,你可以很容易地理解迭代器是如何工作的,这种逻辑可能有点难以理解。因此,理解这个概念的最佳方法是多多敲死代码,多多验证!
代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。
交流
阿里云最近在做活动,低至2折,有兴趣可以看看:https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=pxuujn3r
干货系列文章汇总如下,觉得不错点个Star,欢迎 加群 互相学习。
我是小智,公众号「大迁世界」作者,对前端技术保持学习爱好者。我会经常分享自己所学所看的干货,在进阶的路上,共勉!
关注公众号,后台回复福利,即可看到福利,你懂的。
The text was updated successfully, but these errors were encountered: