人生处万类,知识最为贤。这篇文章主要讲述JS高级程序设计第 4 版:迭代器的学习相关的知识,希望能为你提供帮助。
javascript 高级程序设计第 4 版(后简称高程4),相较于第 3 版,增加了 ES6 至 ES10 的全新内容,删除了旧版过时的内容,并在原有基础上充实了更加翔实的内容。
中文译版于 2020 年发售,妥妥的“新鲜出炉”,你要是问本瓜:当今学 JavaScript 哪家强,我只能说:红宝书第 4 版最在行。
于是乎,借着更文契机,本瓜将开启一个小系列,带你重看一遍高级程序设计4(先前只是跳着跳着看),将抽取精华,用最简单的话解释核心点、尽量把握全局、快速过一遍的同时,记录与工友们分享~~
文章图片
正文
第七章,也是本瓜最感兴趣的一章之一 —— 《迭代器与生成器》(javaScript 的延迟计算依赖的就是它),重点毋庸置疑了。
本篇先只讲:迭代器,以及 for、forEach、for…in、for…of 的演变及区别。
ECMAScript 6 规范新增了两个高级特性:迭代器和生成器。使用这两个特性,能够更清晰、高效、方便地实现迭代。
先回想,咱们以前是怎么去迭代的?
通常大部分情况下都是迭代数组吧?!
let arr = [1,2,3]
for (let index = 0; index < arr.length; index++)
console.log(arr[index]);
通过 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
ES6 默认的 Iterator 接口部署在数据结构的 ?
?Symbol.iterator?
?属性上,该属性本身是一个函数,代表当前数据结构默认的遍历器生成函数。执行该函数
??[Symbol.iterator]()?
?,会返回一个遍历器对象。只要数据结构拥有
??Symbol.iterator?
?属性,那么它就是 “可遍历的” 。原生具备 Iterator 接口的数据结构:
- Array
- Map
- Set
- String
- TypedArray
- 函数的 arguments 对象
- NodeList 对象
?
?for...of?
?
运行原理:- 首先调用遍历对象?
?[Symobo.iterator]()?
? 方法,拿到遍历器对象; - 每次循环,调用遍历器对象?
?next()?
? 方法,得到??value: ..., done: ... ?
? 对象
?.next()?
? 方法,返回:??value?
? 和 ??done?
?,如果 ??done?
? 为 true,则代表:迭代已完成;let arr = [foo, bar];
let iter = arr[Symbol.iterator]();
console.log(iter.next()); //done: false, value: foo
console.log(iter.next()); //done: false, value: bar
console.log(iter.next()); //done: true, value: undefined
我们可以尝试自己写一个极简版的迭代器对象:
class Counter
// Counter 的实例应该迭代 limit 次
constructor(limit)
this.count = 1;
this.limit = limit;
next()
if (this.count < = this.limit)
returndone: false, value: this.count++ ;
else
returndone: true, value: undefined ;
[Symbol.iterator]()
return this;
很神奇,不是吗?
咱就是说 ES6 为啥要搞一个迭代器呢,或者说迭代器的优势在哪里?
JavaScript 中 原有表示 “集合” 的数据结构主要是 “数组(Array)” 和 “对象(Object)”,ES6又新增了 ?目的就是为了:统一!统一各种类型的集合,给出一种通用的、底层的迭代方案!?Map?
?和 ??Set?
?,共四种数据集合,浏览器端还有 ??NodeList?
?类数组结构。为 “集合” 型数据寻求统一的遍历接口,正是 ES6 的 Iterator 诞生的背景。
迭代器是一种设计模式,为遍历不同数据结构的 “集合” 提供统一的接口;能遍历访问 “集合” 数据中的项,不关心项的数据结构
小结
【JS高级程序设计第 4 版(迭代器的学习)】OK,以上便是本篇分享。 觉得不错点个赞吧
推荐阅读
- 防火墙基础之安全策略和NAT(Easy IP)
- Go Web 编程入门(验证器)
- Leetcode 20有效的括号(附JAVA Deque 和LinkedList用法)
- Leetcode 38报数
- pythonnohup python 提示 ImportError: No module named requests
- #夏日挑战赛# FFH从零开始的鸿蒙机器学习之旅-NLP情感分析
- linux搭建redis
- 快速了解常用的对称加密算法,再也不用担心面试官的刨根问底
- 机器学习总结笔记