当前位置:网站首页>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,以上便是本篇分享。 觉得不错点个赞吧,您的鼓励,我的动力,坚持原创质量好文~~ 欢迎评论留言 我是掘金安东尼,输出暴露输入,技术洞见生活。再会吧~~
边栏推荐
- epoch_num和predict_num的换算
- HW is around the corner. Can't you read the danger message?
- Stop using system Currenttimemillis() takes too long to count. It's too low. Stopwatch is easy to use!
- JSP based library management system, including source code, database script, video tutorial for project operation, and video tutorial for thesis writing
- 如何理解fold change?倍数分析?
- Triggers in MySQL
- Implementation of connecting SQL server to Oracle server_ Including query implementation
- Performance of recommender algorithms on top-N recommendation tasks
- Getting started with shell Basics
- “不敢去怀疑代码,又不得不怀疑代码”记一次网络请求超时分析
猜你喜欢

Tables converting to latex format

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

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

HMS core news industry solution: let technology add humanistic temperature

STM32F1与STM32CubeIDE编程实例-光断续传感器驱动

天润云上市在即:VC大佬田溯宁大幅减持,预计将套现2.6亿港元

Traffic replication in istio Service Grid

Redis password modification, startup, view and other operations
![[Nacos cloud native] the first step of reading the source code is to start Nacos locally](/img/f8/d9b848593cf7380a6c99ee0a8158f8.png)
[Nacos cloud native] the first step of reading the source code is to start Nacos locally

Leetcode daily question 202110
随机推荐
Shell基础入门
Stop using system Currenttimemillis() takes too long to count. It's too low. Stopwatch is easy to use!
Record the solution of failing to log in after the alicloud ECS instance is restarted (hands-on practice)
测试组的任务职责和测试的基本概念
leetcode 11. Container with the most water
Views in MySQL
My suggestions on SAP ABAP transformation
transformers VIT图像模型向量获取
Sword finger offer II 114 Alien dictionary
SQL Server 常用函数
Double hands of daily practice of Li Kou 2day9
Interpretation of the thesis -- factorization meets the neighborhood: a multifaceted collaborative filtering model
Traffic replication in istio Service Grid
Getting started with shell Basics
Seven cattle cloud upload picture
Opengauss database source code analysis series articles -- detailed explanation of dense equivalent query technology
谈谈人生风控
Nine good programming habits for 10 years
Some common SQL (version 05 and above) database maintenance scripts
After several years of writing at CSDN, I published "the first book". Thank you!