当前位置: 首页 > news >正文

ES6学习之路:迭代器Iterator和生成器Generator

在这里插入图片描述

迭代器

一、知识背景

  1. 什么是迭代器
    迭代器就是在一个数据集合中不断取出数据的过程
  2. 迭代和遍历的区别
    • 遍历是把所有数据都取出
    • 迭代器注重的是依次取出数据,它不会在意有多少数据,也不会保证能够取出多少或者能够把数据都取完。比如斐波那契额数列,就可以使用迭代器进行无限取值。
  3. 那么,什么是迭代器呢?
    对整个迭代过程的封装,不同的语言有不同的表现形式。通常是一个对象
  4. 迭代模式
    一个设计模式,用于统一迭代过程,并规范了迭代器规格
    • 迭代器应该具有得到下一个数据的能力
    • 迭代器应该具有判断是否还有后续数据的能力

二、ES6里的迭代器

JS中规定,如果一个对象具有next方法,并且该方法返回一个对象,则该对象的格式如下,则认为该对象是一个迭代器。

const obj={next(){retrun{value:xxx, // 值done:xxx// 是否迭代完成}}
}

在这里插入图片描述

  • next方法:用于得到下一批数据
  • 返回的对象
    • value:下一个数据的值
    • done:布尔值,是否完成迭代

三、迭代器创建函数

这个知识点分两个方面来分享 1. 迭代对象内置的迭代器创建函数 2.创建自定义的可迭代对象

3.1、 迭代对象内置的迭代器创建函数

首先,我们需要搞懂什么是迭代器创建函数?

  • ES6规定,如果一个对象具有知名符号属性 [Symbol.iterator],并且属性是一个迭代器创建函数,则该对象是可迭代的(iterable)

    • 迭代器(iterator):一个具有next方法的对象,next方法返回下一个数据并且能指示是否迭代完成
    • 迭代器创建函数(iterator create):一个返回迭代器的函数

js中的可迭代对象有很多,例如数组,集合,映射,类数组,字符串等,以数组为例

const arr=[1,3,4,5,6]console.log(arr)

在这里插入图片描述

执行数组中的迭代器

// 数组
const arr = [1, 2, 3, 4, 5];
// 数组中内置的迭代器创建函数
const iterator = arr[Symbol.iterator]()
// 执行迭代器
iterator.next()

在这里插入图片描述
执行类数组中的迭代器,例如 document.querySelectorAll

// 类数组内置的迭代器
const divs=document.querySelectorAll('div')
const iterator=divs[Sysbol.iterator]()
iterator.next() 

3.2、 普通对象自定义创建 迭代器创建函数

通常,我们使用for of 循环遍历可迭代对象

// 迭代完成后循环结束
for(const item in iterable){// iterable:可迭代对象// item 每次迭代得到的数据
}

可以发现,forof是无法遍历普通对象的,那是因为普通对象不是迭代对象,没有迭代器创建函数和[Symbol.iterator]属性,如果我把这个属性给它加上,普通对象是否会成为迭代对象,从而被forof遍历呢?

// 自定义的可迭代对象
var obj = {
a:1,
b:2,[Symbol.iterator]() {return {next() {return {value: 1,done: false}}}}
}
for(const item of obj){console.log(item)
}

在这里插入图片描述

在这里插入图片描述
结果发现,普通对象是可以通过添加迭代创建函数的方式成为迭代对象的,forof会不断的获取 迭代器中的value值,只要done不为false,就会一直无限取下去。

生成器

一、知识背景

  1. 什么是生成器?
    生成器是一个通过构造函数Generator创建的,也是一个对象,但是无法自己new,只能js引起内部去使用;生成器即是一个迭代器,同事也是一个迭代对象。

  2. 如何创建一个生成器?

    生成器的创建必须使用生成器函数 (Generator Function),返回的是一个生成器对象

  3. 如何书写一个生成器函数呢?

    // 这是一个生成器函数,该函数一定返回一个生成器function *method(){}function* method(){}{*method(){}}*methods=()=>{}
  4. 生成器函数是如何执行的?

    • 生成器函数内部是给生成器每次迭代提供数据的,生成的数据需要放在yield后,才能被迭代出来

          function* test() {console.log('aaaa') }const generator = test()console.log(generator.next()) //  aaaa  { value: undefined, done: true }
      

      在这里插入图片描述

    • yield 是一个关键词,该关键词只能在生成函数的内部使用,意思是 “产生” 一个迭代数据

    • 每次调用生成器的next方法,生成器将运行到下一个yield的位置

      function* test() {console.log('第一次运行')yield 1; //产生的迭代数据console.log('第二次运行')yield 2;//产生的迭代数据console.log('第三次运行')}const generator = test()console.log(generator.next()) // 第一次运行 { value: 1, done: false }console.log(generator.next()) // 第二次运行 { value: 2, done: false }console.log(generator.next()) // 第三次运行 { value: undefined, done: true }
      
    • 生成器可以有返回值return 返回值出现在当迭代器next方法中的done为true时的 value中

      function* test() {console.log('第一次运行')yield 1; //产生的迭代数据console.log('第二次运行')yield 2;//产生的迭代数据console.log('第三次运行')return 10; //函数结束,迭代结束,所以迭代器第一次done为true 的value值可以为10 }const generator = test()console.log(generator.next()) // 第一次运行 { value: 1, done: false }console.log(generator.next()) // 第二次运行 { value: 2, done: false }console.log(generator.next()) // 第三次运行 { value: 10, done: true }console.log(generator.next()) /  { value: undefined, done: true }
      
    • 调用next(参数)方法传值,参数会传给第一次next后的yield,所以第一次调用next(),传参是没有意思的

         function* test() {let info = yield 1 // { value: 1, done: false }console.log(info) // 5info = yield 2 + info // { value: 7, done: false }console.log(info)}const generator = test()console.log(generator.next(111)) // { value: 1, done: false }console.log(generator.next(5)) // { value: 7, done: false }
      
    • 在生成器内部调用其他生成器的函数的迭代数据,注意调用时要加*

         fucntion *a(yield 'a'yield 'b')function *test(){// a() 返回一个生成器对象// yield a() 迭代一个生成器对象yield *a()yield 1yield 2yield 3} const generator = test()console.log(generator.next()) // { value: 'a', done: false } // 会先迭代a方法里的数据
      

二、 生成器常见的api使用方法

除了next方法,下面再接收两个用的比较多的方法

return方法

return方法,调用该方法,可以手动结束整个迭代,后面再次调用next方法时,value值为 undefined

	function* test() {yield 1yield 2yield 3}const generator = test()console.log(generator.next()) //  { value: 1, done: false }console.log(generator.return()) // { value: undefined, done: true }console.log(generator.next()) // { value: undefined, done: true }console.log(generator.next()) // { value: undefined, done: true }console.log(generator.next()) // { value: undefined, done: true }// return 也可以传参数console.log(generator.return(5)) // { value: 5, done: true }

throw方法

throw方法,调用该方法,可以手动抛出一个错误,从而阻止后面数据的迭代

function* test(){yield 1yield 2yield 3
}
const generator = test()
console.log(generator.next()) //  { value: 1, done: false }
console.log(generator.throw(new Error('123'))) // 在  yield 1 报错
console.log(generator.next()) // 不运行
console.log(generator.next()) // 不运行 

相关文章:

ES6学习之路:迭代器Iterator和生成器Generator

迭代器 一、知识背景 什么是迭代器 迭代器就是在一个数据集合中不断取出数据的过程迭代和遍历的区别 遍历是把所有数据都取出迭代器注重的是依次取出数据,它不会在意有多少数据,也不会保证能够取出多少或者能够把数据都取完。比如斐波那契额数列&#…...

如何使用 DynamiCrafter Interp Loop 无缝连接两张照片

DynamiCrafter Interp Loop 是一个基于 AI 的工具,可以用来无缝连接两张照片。它使用深度学习技术来生成中间帧,从而使两张照片之间的过渡更加自然流畅。 使用步骤 访问 DynamiCrafter Interp Loop 网站:https://huggingface.co/spaces/Dou…...

今天起,Windows可以一键召唤GPT-4了

ChatGPT狂飙160天,世界已经不是之前的样子。 新建了人工智能中文站https://ai.weoknow.com 每天给大家更新可用的国内可用chatGPT资源 发布在https://it.weoknow.com 更多资源欢迎关注 微软 AI 大计的最后一块拼图完成了? 把 Copilot 按钮放在 Window…...

使用Kaggle API快速下载Kaggle数据集

前言 在使用Kaggle网站下载数据集时,直接在网页上点击下载可能会很慢,甚至会出现下载失败的情况。本文将介绍如何使用Kaggle API快速下载数据集。 具体步骤 安装Kaggle API包 在终端中输入以下命令来安装Kaggle API相关的包: pip install…...

java 通过 microsoft graph 调用outlook(二)

这次提供一些基础调用方式API PS&#xff1a; getMailFolders 接口返回的属性中&#xff0c;包含了未读邮件数量unreadItemCount 一 POM文件 <!-- office 365 --><dependency><groupId>com.google.guava</groupId><artifactId>guava<…...

【机器学习】代价函数

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;机器学习 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进…...

[leetcode] 100. 相同的树

给你两棵二叉树的根节点 p 和 q &#xff0c;编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同&#xff0c;并且节点具有相同的值&#xff0c;则认为它们是相同的。 示例 1&#xff1a; 输入&#xff1a;p [1,2,3], q [1,2,3] 输出&#xff1a;true示例 2&a…...

08、Lua 函数

Lua 函数 Lua 函数Lua函数主要有两种用途函数定义解析&#xff1a;optional_function_scopefunction_nameargument1, argument2, argument3..., argumentnfunction_bodyresult_params_comma_separated 范例 : 定义一个函数 max()Lua 中函数可以作为参数传递给函数多返回值Lua函…...

【数据分析面试】1. 计算年度收入百分比(SQL)

题目 你需要为公司的营收来源生成一份年度报告。计算截止目前为止&#xff0c;在表格中记录的第一年和最后一年所创造的总收入百分比。将百分比四舍五入到两位小数。 示例&#xff1a; 输入&#xff1a; annual_payments 表 列名类型amountINTEGERcreated_atDATETIMEstatusV…...

数据库SQL语句速查手册

SQL 语句语法AND / ORSELECT column_name(s) FROM table_name WHERE condition AND|OR conditionALTER TABLEALTER TABLE table_name ADD column_name datatypeorALTER TABLE table_name DROP COLUMN column_nameAS (alias)SELECT column_name AS column_alias FROM table_name…...

智慧城市一屏统览,数字孪生综合治理

现代城市作为一个复杂系统&#xff0c;牵一发而动全身&#xff0c;城市化进程中产生新的矛盾和社会问题都会影响整个城市系统的正常运转。智慧城市是应对这些问题的策略之一。城市工作要树立系统思维&#xff0c;从构成城市诸多要素、结构、功能等方面入手&#xff0c;系统推进…...

Python读取PDF文字转txt,解决分栏识别问题,能读两栏

搜索了一下&#xff0c;大致有这些库能将PDF转txt 1. PyPDF/PyPDF2&#xff08;截止2024.03.28这两个已经合并成了一个&#xff09;pypdf PyPI 2. pdfplumber GitHub - jsvine/pdfplumber: Plumb a PDF for detailed information about each char, rectangle, line, et cete…...

微信支付平台与微信服务号关联配置要点

目录 JSAPI支付 前期资料及相关准备 申请微信服务号 服务号配置要点 微信认证 基本配置 功能设置 申请微信支付号 支付号配置要点 设置操作密码 API安全 开发设置 与服务号关联 小结 JSAPI支付 我们的开发应用场景以JSAPI支付为举例&#xff0c;这也是常用的一…...

C++类复习

C类 1. 类内成员函数隐式声明为inline class Str {int x;int y 3; public:inline void fun(){std::cout<<"pf,yes!"<<std::endl;} };这段代码不会报错&#xff0c;但是类内的成员函数隐式声明为inline函数&#xff0c;不需要单独写在前面。因此将成员…...

Spring使用(一)注解

Spring使用 资源 Spring 框架内部使用 Resource 接口作为所有资源的抽象和访问接口&#xff0c;在上一篇文章的示例代码中的配置文件是通过ClassPathResource 进行封装的&#xff0c;ClassPathResource 是 Resource 的一个特定类型的实现&#xff0c;代表的是位于 classpath …...

Linux基本指令篇

在前边&#xff0c;我们已经了解过了Linux操作系统的发展和应用&#xff0c;从该篇起&#xff0c;就正式进入对Linux的学习。 今天我们就来在Xshell上远程登录我们的云服务器。首先我们要知道自己云服务器的公网ip&#xff0c;然后修改一下密码。 点击跳转 修改完密码之后我们…...

CSS实现小车旅行动画实现

小车旅行动画实现 效果展示 CSS 知识点 灵活使用 background 属性下的 repeating-linear-gradient 实现路面效果灵活运用 animation 属性与 transform 实现小车和其他元素的动画效果 动画场景分析 从效果图可以看出需要实现此动画的话&#xff0c;需要position属性控制元素…...

6_相机坐标系_相机4个坐标系详述

相机系列文章是用来记录使用opencv3来完成单目相机和6轴机械臂手眼标定。本人吃饭的主职是linux下6轴机械臂相关应用开发。但对于机械臂运动学、相机应用等都非常感兴趣&#xff0c;所以对一些线性代数基础薄弱又想深入了解机械臂内部运算的同志比较有体会。由于是探索性学习&a…...

软考 - 系统架构设计师 - 敏捷开发方法

前言 敏捷开发方法是一种以人为核心、迭代、循序渐进的软件开发方法。它强调团队合作、客户需求和适应变化&#xff0c;旨在通过快速迭代和反馈来快速交付高质量的软件产品。 敏捷开发方法的优势在于能够快速响应变化、提高开发效率和质量、增强团队协作和沟通&#xff0c;并降…...

Django 仿博客园练习

数据库搭建 部分功能介绍 【一】注册 &#xff08;1&#xff09;效果显示、简单简介 主要亮点 结合了layui和forms组件默认头像可以随着性别的选择发生改变自定义头像可以实时更新显示forms组件报错信息可以局部刷新显示在对应框体下面 没有直接使用layui的前端验证后端验证…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…...

小木的算法日记-多叉树的递归/层序遍历

&#x1f332; 从二叉树到森林&#xff1a;一文彻底搞懂多叉树遍历的艺术 &#x1f680; 引言 你好&#xff0c;未来的算法大神&#xff01; 在数据结构的世界里&#xff0c;“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的&#xff0c;它…...

规则与人性的天平——由高考迟到事件引发的思考

当那位身着校服的考生在考场关闭1分钟后狂奔而至&#xff0c;他涨红的脸上写满绝望。铁门内秒针划过的弧度&#xff0c;成为改变人生的残酷抛物线。家长声嘶力竭的哀求与考务人员机械的"这是规定"&#xff0c;构成当代中国教育最尖锐的隐喻。 一、刚性规则的必要性 …...