首页 > 其他分享 >ES6学习之路:迭代器Iterator和生成器Generator

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

时间:2024-03-25 16:59:03浏览次数:21  
标签:ES6 console Iterator 迭代 generator 生成器 value next log

在这里插入图片描述

迭代器

一、知识背景

  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()) // 不运行 

标签:ES6,console,Iterator,迭代,generator,生成器,value,next,log
From: https://blog.csdn.net/Code_King006/article/details/137005963

相关文章

  • MyBatisPlus新版代码生成器(Velocity模板引擎详解)
    文章目录一、Velocity模板引擎1、velocity简介2、快速入门3、基础语法4、注释5、变量6、循环7、条件8、引入资源9、macro宏二、MybatisPlus代码生成器1、MP代码生成器2、自定义velocity模板2.1、MybatisPlus自带模板和变量2.2、公共模板`common.vm`文件2.3、实体模板`en......
  • GUID生成器 - 开源研究系列文章
          今天整理原来的代码,把GUID生成器的源码进行了整理。原来的C#和VB6的代码都进行了整理。然后把这个代码发布出来,让需要的读者能够进行复用。 1、项目目录;  2、源码介绍;  3、运行界面;  4、使用介绍......
  • Mybatis的代码生成器
    1.首先在pom.xml文件上面添加以下依赖项<dependencies><!--MyBatis相关--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.5</version></d......
  • Day25 迭代器之Iterator底层
    Day25迭代器之Iterator底层一、迭代器1、概念:迭代器(Iterator)是一种用于遍历集合(Collection)元素的接口,它提供了统一的方式来访问集合中的元素,而不暴露集合的内部结构。通过迭代器,我们可以依次访问集合中的每个元素,进行遍历和操作。2、使用步骤:获取集合的迭代器:Iterat......
  • python之迭代器和生成器的使用方式
    下面我将分别介绍迭代器和生成器的使用示例:迭代器示例:迭代器是一种对象,它可以在遍历时逐个访问元素而不需要将所有元素加载到内存中。下面是一个简单的迭代器示例,该迭代器生成斐波那契数列的前n个数字:classFibonacciIterator:def__init__(self,n):self.n=......
  • fastposter v2.19.0 一款很哇塞的海报生成器
    ......
  • 【python】(02)初识迭代器Iterator
    系列文章回顾【python】(01)初识装饰器Decorator【python】(02)初识迭代器Iterator文章目录一.迭代器的定义二.迭代器的作用三.实际代码示例四.使用注意事项五.常见问题迭代器是Python中非常重要的概念,通过灵活运用迭代器可以实现高效的数据遍历和处......
  • Snowflake 分布式id生成器--生成唯一ID
    在Snowflake算法中,通常包含以下几个部分来构造一个唯一的ID:时间戳(Timestamp):占据了64位ID中的高41位,用来表示生成ID的时间。通过时间戳的递增,保证了生成的ID是递增且唯一的。数据中心ID(DataCenterID):用于标识不同的数据中心,通常占据了5位。机器ID(Worker......
  • es6——proxy
    1、概述Proxy用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(metaprogramming),即对编程语言进行编程。Proxy可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。......
  • es6学习笔记
    11.15星期三学习地址:ECMAScript6入门http://es6.ruanyifeng.com/阮一峰下载nodejs,NodeJS环境搭建及sublimeText3配置NodeJs环境,添加前端插件。一、es6简介:二者关系:ECMAScript和JavaScript的关系是,前者是后者的规格,后者是前者的一种实现(另外的ECMAScript方言还......