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

news2024/10/7 0:27:56

在这里插入图片描述

迭代器

一、知识背景

  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) // 5
        	info = 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 1
        	    yield 2
        	   yield 3
        } 
        const generator = test()
        console.log(generator.next()) // { value: 'a', done: false } // 会先迭代a方法里的数据
      

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

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

return方法

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

	function* test() {
		yield 1
		yield 2
	    yield 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 1
     yield 2
     yield 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()) // 不运行 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1561043.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

离散时间动态系统的集成自适应动态规划智能控制-北科大博毕

主要内容: 传统值迭代产生迭代控制策略,给出稳定性和吸引域判据;传统值迭代则迭代过程中得到可容许策略折扣因子对迭代控制策略可容许的影响,神经网络对未知系统建模,讨论模型网络权重更新情况下参数误差和系统状态估…

TikTok零播放?可能是海外代理IP的问题

在当今社交媒体的蓬勃发展中,TIKTOK作为一款备受欢迎的短视频平台,其直播功能也逐渐受到用户的青睐。然而,有时候跨境电商商家在进行直播时却面临着一个令人头疼的问题:没有观众。这时候,海外代理IP可能是一个潜在的原…

吴恩达:别光盯着GPT-5,用GPT-4做个智能体可能提前达到GPT-5的效果

最近,斯坦福大学教授吴恩达在演讲中提到,他们发现,基于 GPT-3.5 构建的智能体工作流在应用中表现比 GPT-4 要好。 AI 智能体是去年很火的一个话题,但是 AI 智能体到底有多大的潜力,很多人可能没有概念。 最近&#x…

【环境搭建】(四)ubuntu22.04系统安装Opencv4.8.0+Opencv-contrib4.8.0

一个愿意伫立在巨人肩膀上的农民...... 一、安装下载所需工具 1.打开终端,输入以下命令来更新软件源: sudo apt-get update 2.安装wget: sudo apt-get install wget 3.下载opencv和opencv-contrib包: wget -O opencv-4.8.0.…

ISP-VPN实验

文章目录 ISP-VPN实验一,实验拓扑二、实验要求三、IP规划四、实验配置1、IP配置R1的配置R2的配置R3的配置R4的配置R5的配置 2、配置缺省路由3、认证与被认证配置4、HDLC封装5、构建MGRE和GRE6、整个私有网络基于RIP全网可达7、查看路由配置和PC端配置8、PC端pingR5的…

Vue element-plus 导航栏 [el-menu]

导航栏 [el-menu] Menu 菜单 | Element Plus el-menu有很多属性和子标签,为网站提供导航功能的菜单。 常用标签: 它里面有两个子标签。el-menu-item,它其实就是el-menu每一个里面的item,item就是真实匹配到路由的每个栏目&#…

【Python使用】嘿马头条完整开发md笔记第3篇:数据库,1 新增【附代码文档】

嘿马头条项目从到完整开发笔记总结完整教程(附代码资料)主要内容讲述:课程简介,ToutiaoWeb虚拟机使用说明1 产品介绍,2 原型图与UI图,3 技术架构,4 开发,1 需求,2 注意事项。数据库,理解ORM1 简介,2 安装,3 数据库连接…

使用CRXjs、Vite、Vue 开发 Chrome 多页面插件,手动配置 vite.config.ts 和 manifest.json 文件

一、使用CRXjs、Vite、Vue 开发 Chrome 多页面插件,手动配置 vite.config.ts 和 manifest.json 文件 一、创建 Vue 项目 1. 使用 Vite 创建 Vue 项目 npm create vitelatest # npm yarn create vite # yarn pnpm create vite # pnpm选择 Vue 和 TS 进入项目…

SpringBoot微服务实现深度学习:构建AGI道路的基石+实战案例演示

🎉🎉欢迎光临,终于等到你啦🎉🎉 🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀 🌟持续更新的专栏《Spring 狂野之旅:从入门到入魔》 &a…

4月4日生效!管控升级!继续围堵 | 百能云芯

据路透社29日报道,美国拜登政府当天修改规则,升级针对中国人工智能(AI)芯片和相关工具出口管制的措施。报道声称,这是美国以国家安全为由阻碍中国芯片制造业发展的努力的一部分。 美国商务部下属的工业与安全局&#x…

移动硬盘损坏打不开?别慌,数据恢复有妙招!

移动硬盘作为我们日常存储和传输数据的重要工具,一旦遇到损坏打不开的情况,无疑会让我们倍感焦虑。毕竟,其中存储的文件可能关乎工作、学习或生活的方方面面,一旦丢失,后果不堪设想。那么,当移动硬盘损坏打…

UE5 SQLite笔记

开发环境: 系统:Windows 10 64 bit 引擎:Unreal Engine 5.1.1 IDE:JetBrains Rider 2023.2.1 语言:C 工具:DB Browser for SQLite SQLite数据类型: //INTEGER TEXT BLOB REAL NUMERIC/*integer…

使用Pilotfish扩展Sui执行能力

Pilotfish第一个多机智能合约执行引擎,使Sui网络的验证节点可以利用多台机器,并在负载增加时自动扩展以执行更多的交易。这一目标实现不会影响可靠性或功能完整性。 Pilotfish可以从内部执行机器的故障中恢复,并支持Sui的全面动态操作。其流…

TCP粘包是怎么回事,如何处理?

还是大剑师兰特:曾是美国某知名大学计算机专业研究生,现为航空航海领域高级前端工程师;CSDN知名博主,GIS领域优质创作者,深耕openlayers、leaflet、mapbox、cesium,canvas,webgl,ech…

Wafer的T7 Code是什么,怎么来的

1、T7 Code是什么 在半导体Cim系统中,waferstart 业务需要支持 Sorter 读取 Wafer 的 T7 Code,与 MES 的 Wafer ID 进行绑定,以便向 前追溯 Wafer 历史,那么问题来了,T7code 是什么 Wafer的T7 Code是一种背面刻号,用于标识双面抛光的晶圆。这种标记采用二维矩阵代码符号,…

海外问卷调查保姆级教程,看完这篇就不用再找别的了

大家好,我是橙河老师,最近很多小伙伴在问海外问卷调查怎么做?这篇文章就从环境搭建到做问卷的过程,全部展示给大家,希望大家能够学会。 这个是保姆级教程了,争取一次就把大家教会,多看教程&…

Docker服务

任务描述:请采用podman,实现有守护程序的容器应用。 (1)在linux2上安装docker-ce,导入rocky镜像。 (2)创建名称为skills的容器,映射本机的8000端口到容器的80端口,在容…

Object类-equals方法

细节:1、equals方法默认先比较两个对象的地址是否相同(即两个对象是否是同一个对象),如果是同一个对象返回true;如果不是同一个对象,返回false。 2、子类中重写父类的equals方法后,比较的是两个…

如何算通过了PMP考试?

一般在PMP考试结束后的6-8周便可以在PMI网站查询到成绩,或者查看PMI发送给考生的成绩邮件。如果成绩上显示“PASS”就是通过,“FAIL”就是没通过。 需要注意的是你看到的成绩不是直接的分数,而是用A\T\B\N表示的,即Above Target(…

2024银行业最新数字化转型的方法与路径

银行业数字化转型是一场由思想到行动、由顶层到基层、由内部到外部的深刻变革, 需要科学方法论的指导。在推动体系性重塑、开放生态建设、业务科技融合、基础设施升 级以及体制机制变革等探索和实践中,银行业逐步形成从顶层设计到数字化能力建设&#xf…