当前位置:网站首页>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,以上便是本篇分享。 觉得不错点个赞吧,您的鼓励,我的动力,坚持原创质量好文~~ 欢迎评论留言 我是掘金安东尼,输出暴露输入,技术洞见生活。再会吧~~
边栏推荐
- SQL and Oracle statements for eliminating duplicate records
- Neuron+eKuiper 实现工业物联网数据采集、清理与反控
- Instanceinforeplicator class of Eureka (service registration auxiliary class)
- leetcode每日一题202110
- 七牛云上传图片
- Ppt data collection methods and analysis skills
- What does Huawei's minutes on patents say? (including Huawei's top ten inventions)
- 程序员要不要选择软件人才外包公司?
- Double hands of daily practice of Li Kou 2day9
- 史蒂芬·柯维写给年轻人的高效工作秘笈
猜你喜欢

Traffic replication in istio Service Grid

《Kubernetes监控篇:Grafana通过自动化方式添加datasource和dashboard》

hw在即,你还不会看危险报文?
Redis+Caffeine两级缓存的实现

JSP based library management system, including source code, database script, video tutorial for project operation, and video tutorial for thesis writing

"Dare not doubt the code, but have to doubt the code" a network request timeout analysis

leetcode-区间dp

测试组的任务职责和测试的基本概念

如何给VR全景作品添加遮罩?作用是什么?

leetcode-子序列/子串問題
随机推荐
聊一聊数据库的行存与列存
Docker installing PostgreSQL
Oracle cursor
leetcode-背包问题
openGauss数据库源码解析系列文章—— 密态等值查询技术详解
如何保护WordPress网站免受网络攻击?采取安全措施至关重要
在CSDN写文几年,我出了“第一本书“,感恩!
Traffic replication in istio Service Grid
epoch_num和predict_num的换算
Seven cattle cloud upload picture
20 good habits of outstanding professionals
七牛云上传图片
天润云上市在即:VC大佬田溯宁大幅减持,预计将套现2.6亿港元
Linux setting enables Oracle10g to start automatically
Acwing week 52
程序员要不要选择软件人才外包公司?
SQL Server common functions
If the programmer tells the truth during the interview
Query escape in Oracle expdp export
Query rewriting for opengauss kernel analysis