当前位置:网站首页>JS高级程序设计第 4 版:迭代器的学习
JS高级程序设计第 4 版:迭代器的学习
2022-06-22 12:49:00 【51CTO】
JavaScript 高级程序设计第 4 版(后简称高程4),相较于第 3 版,增加了 ES6 至 ES10 的全新内容,删除了旧版过时的内容,并在原有基础上充实了更加翔实的内容。
中文译版于 2020 年发售,妥妥的“新鲜出炉”,你要是问本瓜:当今学 JavaScript 哪家强,我只能说:红宝书第 4 版最在行。
于是乎,借着更文契机,本瓜将开启一个小系列,带你重看一遍高级程序设计4(先前只是跳着跳着看),将抽取精华,用最简单的话解释核心点、尽量把握全局、快速过一遍的同时,记录与工友们分享~~

正文
第七章,也是本瓜最感兴趣的一章之一 —— 《迭代器与生成器》(JavaScript 的延迟计算依赖的就是它),重点毋庸置疑了。
ECMAScript 6 规范新增了两个高级特性:迭代器和生成器。使用这两个特性,能够更清晰、高效、方便地实现迭代。
本篇先只讲:迭代器,以及 for、forEach、for…in、for…of 的演变及区别。
先回想,咱们以前是怎么去迭代的?
通常大部分情况下都是迭代数组吧?!
通过 for 循环去迭代,有什么问题吗?高程给出了解释:
- **迭代之前需要事先知道如何使用数据结构。**数组中的每一项都只能先通过引用取得数组对象, 然后再通过[]操作符取得特定索引位置上的项。并且,这种情况并不适用于所有数据结构。
- **遍历顺序并不是数据结构固有的。**通过递增索引来访问数据是特定于数组类型的方式,并不适 用于其他具有隐式顺序的数据结构。
什么意思?即: for 循环不适用遍历所有数据结构;
ES5 发布了 forEach ,并没有做出任何改善,反而也是弊端多多:
- 不能使用 break 语句中断循环;
- 不能使用return 语句返回到外层函数;
for-in 呢?for-in 是为遍历普通对象设计的,可以得到字符串类型的键,不适用于数组遍历。
for-of 呢?没错,它是主角!
for-of 循环语句通过方法调用来遍历各种集合:数组、NodeList、字符串、Maps 对象、Sets 对象等等
这些对象都有一个共通的特点:它们都有一个迭代器方法!
let
str
=
'abc';
let
arr
= [
'a',
'b',
'c'];
let
map
=
new
Map().
set(
'a',
1).
set(
'b',
2).
set(
'c',
3);
let
set
=
new
Set().
add(
'a').
add(
'b').
add(
'c');
let
els
=
document.
querySelectorAll(
'div');
// 这些类型都实现了迭代器工厂函数
console.
log(
str[
Symbol.
iterator]);
// f values() { [native code] }
console.
log(
arr[
Symbol.
iterator]);
// f values() { [native code] }
console.
log(
map[
Symbol.
iterator]);
// f values() { [native code] }
console.
log(
set[
Symbol.
iterator]);
// f values() { [native code] }
console.
log(
els[
Symbol.
iterator]);
// f values() { [native code] }
// 调用这个工厂函数会生成一个迭代器
console.
log(
str[
Symbol.
iterator]());
// StringIterator {}
console.
log(
arr[
Symbol.
iterator]());
// ArrayIterator {}
console.
log(
map[
Symbol.
iterator]());
// MapIterator {}
console.
log(
set[
Symbol.
iterator]());
// SetIterator {}
console.
log(
els[
Symbol.
iterator]());
// ArrayIterator {}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
ES6 默认的 Iterator 接口部署在数据结构的 Symbol.iterator属性上,该属性本身是一个函数,代表当前数据结构默认的遍历器生成函数。执行该函数 [Symbol.iterator](),会返回一个遍历器对象。只要数据结构拥有 Symbol.iterator属性,那么它就是 “可遍历的” 。
原生具备 Iterator 接口的数据结构:
- Array
- Map
- Set
- String
- TypedArray
- 函数的 arguments 对象
- NodeList 对象
所有拥有 Symbol.iterator 的对象被称为可迭代的。
for...of 运行原理:
- 首先调用遍历对象
[Symobo.iterator]() 方法,拿到遍历器对象; - 每次循环,调用遍历器对象
next() 方法,得到{value: ..., done: ... } 对象
.next() 方法,返回:value 和 done,如果 done 为 true,则代表:迭代已完成;
我们可以尝试自己写一个极简版的迭代器对象:
class
Counter {
// Counter 的实例应该迭代 limit 次
constructor(
limit) {
this.
count
=
1;
this.
limit
=
limit;
}
next() {
if (
this.
count
<=
this.
limit) {
return {
done:
false,
value:
this.
count
++ };
}
else {
return {
done:
true,
value:
undefined };
}
}
[
Symbol.
iterator]() {
return
this;
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
很神奇,不是吗?
咱就是说 ES6 为啥要搞一个迭代器呢,或者说迭代器的优势在哪里?
JavaScript 中 原有表示 “集合” 的数据结构主要是 “数组(Array)” 和 “对象(Object)”,ES6又新增了
Map和 Set,共四种数据集合,浏览器端还有 NodeList类数组结构。为 “集合” 型数据寻求统一的遍历接口,正是 ES6 的 Iterator 诞生的背景。
目的就是为了:统一!统一各种类型的集合,给出一种通用的、底层的迭代方案!
迭代器是一种设计模式,为遍历不同数据结构的 “集合” 提供统一的接口;能遍历访问 “集合” 数据中的项,不关心项的数据结构
小结
OK,以上便是本篇分享。 觉得不错点个赞吧,您的鼓励,我的动力,坚持原创质量好文~~ 欢迎评论留言 我是掘金安东尼,输出暴露输入,技术洞见生活。再会吧~~
边栏推荐
- Shell基础入门
- 线下实体店结合VR全景,让虚拟购物更加真实
- Double hands of daily practice of Li Kou 2day9
- uniapp app 端截屏且保存到本地
- Problème de sous - séquence / substrat leetcode
- leetcode-背包问题
- 聊一聊数据库的行存与列存
- leetcode 854. String with similarity K
- Common writing methods and excellent examples of acknowledgments in graduation thesis writing
- 【Nacos云原生】阅读源码第一步,本地启动Nacos
猜你喜欢

Oceanbase database helps the ideal automobile intelligent production line to realize automatic recovery within 30 seconds

Istio服务网格中的流量复制

史蒂芬·柯维写给年轻人的高效工作秘笈

在CSDN写文几年,我出了“第一本书“,感恩!

History of hash index design

Leetcode interval DP

Neuron+eKuiper 实现工业物联网数据采集、清理与反控

“不敢去懷疑代碼,又不得不懷疑代碼”記一次網絡請求超時分析

数据库 就业咨询系统求各位帮下忙

JSP based library management system, including source code, database script, video tutorial for project operation, and video tutorial for thesis writing
随机推荐
Traffic replication in istio Service Grid
毕业论文写作中致谢词的常见写法及优秀范文
“不敢去怀疑代码,又不得不怀疑代码”记一次网络请求超时分析
hw在即,你还不会看危险报文?
My suggestions on SAP ABAP transformation
Query rewriting for opengauss kernel analysis
Leetcode math problems
Leetcode union search set
《Kubernetes监控篇:Grafana通过自动化方式添加datasource和dashboard》
防火墙基础之策略部署
Talk about row storage and column storage of database
Which securities company is good for retail investors to open an account? Is it safe to open a mobile account?
"Dare not doubt the code, but have to doubt the code" a network request timeout analysis
leetcode-二分法
如何给VR全景作品添加遮罩?作用是什么?
Locks in MySQL
华为这份关于专利的会议纪要,都说了什么?(内含华为十大发明彩蛋)
Detailed explanation of rules and ideas for advance sale of deposit
融云:让银行轻松上“云”
"N'osez pas douter du Code, vous devez douter du Code" notez une analyse de délai de demande réseau