-
new Map([iterable])
-
new WeakMap([iterable])
-
new Set([iterable])
-
new WeakSet([iterable])
-
Promise.all([iterable])
-
Promise.race([iterable])
-
Array.from([iterable])
还有需要一个可迭代的对象,否则,它将抛出一个类型错误,例如:
-
for ... of
-
...
(展开操作符)
const [a, b, ..] = iterable
(解构赋值)
yield*
(生成器)
JavaScript中已有许多内置的可迭代项:
String
,Array
,TypedArray
,Map
,Set
。
迭代器和可迭对象遵循迭代协议
。
协议是一组接口,并规定了如何使用它们。
迭代器遵循迭代器协议,可迭代遵循可迭代协议。
可迭代的协议
要使对象变得可迭代,它必须实现一个通过Symbol.iterator
的迭代器方法,这个方法是迭代器的工厂。
使用 TypeScript,可迭代协议如下所示:
interface Iterable {
Symbol.iterator : Iterator;
}
Symbol.iterator]()
是无参数函数。 在可迭代对象上调用它,这意味着我们可以通过this
来访问可迭代对象,它可以是常规函数或生成器函数。
迭代器协议
迭代器协议定义了产生值序列的标准方法。
为了使对象成为迭代器,它必须实现next()
方法。 迭代器可以实现return()
方法,我们将在本文后面讨论这个问题。
使用 TypeScript,迭代器协议如下所示:
interface Iterator {
next() : IteratorResult;
return?(value?: any): IteratorResult;
}
IteratorResult
的定义如下:
interface IteratorResult {
value?: any;
done: boolean;
}
-
done
通知消费者迭代器是否已经被使用,false
表示仍有值需要生成,true
表示迭代器已经结束。 -
value
可以是任何 JS 值,它是向消费者展示的值。
当done
为true
时,可以省略value
。
迭代器和可以可迭代对象可以用下面这张图来表示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qu7BEdCY-1606263454066)(/img/bVbOVew)]
基础知识介绍完了,接着,我们来配合一些事例来加深我们的映像。
范围迭代器
我们先从一个非常基本的迭代器开始,createRangeIterator
迭代器。
我们手动调用it.next()
以获得下一个IteratorResult
。 最后一次调用返回{done:true}
,这意味着迭代器现在已被使用,不再产生任何值。
function createRangeIterator(from, to) {
let i = from;
return {
next() {
if (i <= to) {
return { value: i++, done: false };
} else {
return { done: true };
}
}
}
}
const it = createRangeIterator(1, 3);
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-auJn06E3-1606263454068)(/img/bVbOViQ)]
可迭代范围迭代器
在本文的前面,我已经提到 JS 中的某些语句需要一个可迭代的对象。 因此,我们前面的示例在与for ... of
循环一起使用时将不起作用。
但是创建符合迭代器
和可迭代协议
的对象非常容易。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SUzWxihn-1606263454070)(/img/bVbOVxd)]
function createRangeIterator (from, to) {
let i = from
return {
[Symbol.iterator] () {
return this
},
next() {
if (i <= to) {
return { value: i++, done: false }
} else {
return { done: true }
}
}
}
}
const it = createRangeIterator(1, 3)
for (const i of it) {
console.log(i)
}
迭代器可以表示无限制大小的序列,因为它们仅在需要时才计算值。
注意不要在无限迭代器上使用扩展运算符(...
),JS 将尝试消费迭代器,由于迭代器是无限的,因此它将永远不会结束。 所以你的应用程序将崩溃,因为内存已被耗尽 😱
同样,for ... of
循环也是一样的情况,所以要确保能退出循环:
function createEvenNumbersIterator () {
let value = 0
return {
[Symbol.iterator] () {
return this
},
next () {
value += 2
return { value, done: false}
}
}
}
const it = createEvenNumbersIterator()
const [a, b, c] = it
console.log({a, b, c})
const [x, y, z] = it
console.log({ x, y, z })
for (const even of it) {
console.log(even)
if (even > 20) {
break
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ziQZUuHt-1606263454074)(/img/bVbOVz3)]
关闭迭代器
前面我们提到过,迭代器可以有选择地使用return()
方法。 当迭代器直到最后都没有迭代时使用此方法,并让迭代器进行清理。
for ... of
循环可以通过以下方式更早地终止迭代:
-
break
-
continue
-
throw
-
return
function createCloseableIterator () {
let idx = 0
const data = [‘a’, ‘b’, ‘c’, ‘d’, ‘e’]
function cleanup() {
console.log(‘Performing cleanup’)
}
return {
Symbol.iterator { return this },
next () {
if (idx <= data.length - 1) {
return { value: data[idx++], done: false }
} else {
cleanup()
return { done: true }
}
},
return () {
cleanup()
return { done: true }
}
}
}
const it = createCloseableIterator()
for (const value of it) {
console.log(value)
if (value === ‘c’) {
break
}
}
console.log(‘\n----------\n’)
const _it = createCloseableIterator();
for (const value of _it) {
console.log(value);
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WitbqqEm-1606263454076)(/img/bVbOVDp)]
-
如果知道迭代器已经结束,则手动调用
cleanup()
函数。 -
如果突然完成,则
return()
起作用并为我们进行清理。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
文末
从转行到现在,差不多两年的时间,虽不能和大佬相比,但也是学了很多东西。我个人在学习的过程中,习惯简单做做笔记,方便自己复习的时候能够快速理解,现在将自己的笔记分享出来,和大家共同学习。
个人将这段时间所学的知识,分为三个阶段:
第一阶段:HTML&CSS&JavaScript基础
第二阶段:移动端开发技术
第三阶段:前端常用框架
CodeChina开源项目:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
-
推荐学习方式:针对某个知识点,可以先简单过一下我的笔记,如果理解,那是最好,可以帮助快速解决问题;
-
大厂的面试难在,针对一个基础知识点,比如JS的事件循环机制,不会上来就问概念,而是换个角度,从题目入手,看你是否真正掌握。所以对于概念的理解真的很重要。
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
t/644efd4ddd0f8d43535f1982ec0da6e4.png)
CodeChina开源项目:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
-
推荐学习方式:针对某个知识点,可以先简单过一下我的笔记,如果理解,那是最好,可以帮助快速解决问题;
-
大厂的面试难在,针对一个基础知识点,比如JS的事件循环机制,不会上来就问概念,而是换个角度,从题目入手,看你是否真正掌握。所以对于概念的理解真的很重要。
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算