Iterator迭代器

一、基本概念

Iterator迭代器是一种接口,为不同的数据结构提供一种访问机制,即for … of 循环。当使用for…of循环遍历某种数据结构时,该循环会自动去寻找 Iterator 接口。任何数据结构只要部署Iterator接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。

例如:

  const arr = [1, 2, 3]
  for (const number of arr) {
    console.log(number)
  }

二、实现原理

数组之所以能够支持for of 遍历,是因为ES6提前在数组中预置了一个接口:Symbol(Symbol.iterator)
在这里插入图片描述
其实for of是一个语法糖,它其实就是执行Symbol(Symbol.iterator)接口来得到迭代器对象,然后通过这个迭代器对象获取到对应数据的的。
我们可以执行一下数组的迭代器接口看一下得到的是什么:

  const arr = [1, 2, 3]
  const iter = arr[Symbol.iterator]()
  console.log(iter)

在这里插入图片描述
我们可以看到迭代器上有一个next方法,我们可以执行一下这个next方法:

  console.log(iter.next())
  console.log(iter.next())
  console.log(iter.next())
  console.log(iter.next())

在这里插入图片描述
我们可以看到,我们通过不断调用next()方法,就能获取所有的数据了。
结论:for of 循环只是提供了一个语法糖,通过不断调用迭代器接口提供的迭代器中的next方法来获取所有的数据

ES6规定,默认的迭代器接口都部署在数据结构的Symbol.iterator属性上,或者说,一个数据结构只要具有Symbol.iterator属性,那么它就是“可遍历的”,即可以使用for of 循环进行遍历。Symbol.iterator属性本身是一个函数,就是当前数据结构迭代器的生成函数,执行这个函数,就会得到一个遍历器。

原生具备Iterator接口的数据结构有:

  • Array
  • Set
  • Map
  • String
  • arguments对象
  • NodeList对象
  • URLSearchParams对象 等等

三、手动实现

知道原理之后,我们可以尝试手动实现一个简单的遍历器
比如:如何给一个对象增加一个遍历器?

1.利用原有迭代器接口

  const obj = {
    0: '张三',
    1: '李四',
    2: '王二'
  }

可以观察出这种对象是线性的,那么我们可以去利用数组的迭代器接口:

  const obj = {
    0: '张三',
    1: '李四',
    2: '王二',
    length: 3,
    [Symbol.iterator]: Array.prototype[Symbol.iterator]
  }
  for (const objElement of obj) {
    console.log(objElement)
  }

在这里插入图片描述
这样我们就借助数组的迭代器接口来实现了对象的遍历,当前,这种投机取巧的方式使用场景是很有限的,只是为了让大家更好理解迭代器接口。

2.手动实现

因为迭代器只支持线性遍历,所以手动实现的使用场景也不多,但是我们可以模拟一个场景:让一个类的私有属性支持循环遍历。
比如:

  class ObjClass {
    #list = ['a', 'b', 'c', 'd']
  }
  const obj = new ObjClass()
  console.log(obj.#list) // Error

我们知道 #list现在是一个私有属性,我们希望外部去修改它,但是我们又希望可以支持外部进行遍历,这样我们就能使用手动实现迭代器的方式来做。

  class ObjClass {
    #list = ['a', 'b', 'c', 'd']; // 私有属性list
    [Symbol.iterator]() {
      let index = 0
      // 返回迭代器对象
      return {
        next: () => {
          if (index < this.#list.length) {
            // 返回数据
            return {
              value: this.#list[index++], // 执行之后将index + 1
              done: false
            }
          } else {
            // 返回截止标识
            return {
              value: undefined,
              done: true
            }
          }
        }
      }
    }
  }
  const obj = new ObjClass()
  // 直接遍历当前实例化对象,就能直接遍历私有属性 #list了
  for (const listItem of obj) {
    console.log(listItem)
  }

在这里插入图片描述

四.其他使用场景

如果我们对刚才的实例化对象使用展开运算符的时候我们就会得到一个有趣的结果。

正常对对象展开时:

const objTest = {
    a: '1',
    b: '2'
  }
console.log({...objTest})

在这里插入图片描述
手动添加迭代器接口的对象:

class ObjClass {
    #list = ['a', 'b', 'c', 'd']; // 私有属性list
    [Symbol.iterator]() {
      let index = 0
      // 返回迭代器对象
      return {
        next: () => {
          if (index < this.#list.length) {
            // 返回数据
            return {
              value: this.#list[index++], // 执行之后将index + 1
              done: false
            }
          } else {
            // 返回截止标识
            return {
              value: undefined,
              done: true
            }
          }
        }
      }
    }
  }
  const obj = new ObjClass()
  console.log({...obj})
  console.log([...obj])

在这里插入图片描述
这是因为我们调用 ...展开运算符时都会默认先调用迭代器接口。所以如果我们手动添加了迭代器接口之后,执行展开运算符就会得到我们迭代器接口的值了。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot中对Spring AOP的实现

文章目录 SpringBoot中对Spring AOP的实现AOP简介引入依赖AOP体系与概念编写AOP切面类启动SpringBoot项目然后访问controller控制器对环绕通知放行execution表达式的含义通过注解方式定义切点 SpringBoot中对Spring AOP的实现 AOP简介 AOP (Aspect Oriented Programming), 面…

智能视频监控平台EasyCVR接口调用注意事项汇总!

TSINGSEE青犀视频监控汇聚平台EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安防视频监控的能力&…

前端,CSS,背景颜色跟随轮播图片改变而改变(附源码)

首先看效果&#xff01; 比如轮播图时红色&#xff0c;那么背景的底色也是红色&#xff0c;轮播图时黄色&#xff0c;背景的底色也是黄色&#xff0c;这就是根据轮播图的图片切换&#xff0c;而改变背景颜色随轮播图颜色一致 话不多说&#xff0c;直接上代码&#xff01;非常简…

Python使用psycopg2读取PostgreSQL的geometry字段出现二进制乱码

1、问题 读取geometry字段出现二进制乱码 查询语句&#xff1a; sql "select * from public"Note: 这种写法在PostgreSQL中直接查询, 没有问题&#xff0c;不会报错。 但是在Python中查询&#xff0c;如果导出的geom还是一长串的geometry 格式的话&#xff0c; …

【计网 EMail】计算机网络 EMail协议详解:中科大郑烇老师笔记 (五)

目录 0 引言1 电子邮件EMail1.1 组成1.2 SMTP协议1.3 案例&#xff1a;Alice给Bob发送报文1.4 SMTP总结1.5 邮件报文格式1.6 POP3协议和IMAP协议 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;计算机四大基础专栏&#x1f4dc; 其他章节&#xf…

计算机网络(谢希仁)第八版课后题答案(第一章)

1.计算机网络可以向用户提供哪些服务 连通性:计算机网络使上网用户之间可以交换信息&#xff0c;好像这些用户的计算机都可以彼此直接连通一样。 共享:指资源共享。可以是信息、软件&#xff0c;也可以是硬件共享。 2.试简述分组交换的要点 采用了存储转发技术。把报文(要发…

每日一练 | 华为认证真题练习Day122

1、路由器所有的接口属于同一个广播域。 A. 对 B. 错 2、下列配置默认路由的命令中&#xff0c;正确的是&#xff08;&#xff09;。 A. [Huawei]ip route-static 0.0.0.0 0.0.0.0 192.168.1.1 B. [Huawei-Serial0]ip route-static 0.0.0.0 0.0.0.0 0.0.0.0 C. [Huawei]ip…

如何快速从Oracle迁移到Mysql?

database 一、使用navicat工具二、问题 一、使用navicat工具 1、选择工具中的数据传输 2、源选Oracle,目标选Mysql,一直点下一步 二、问题 1、navicat连接oracle报错:Oracle library is not loaded navicat是通过oracle的客户端连接oracle的,报这个错是因为navicat for or…

Penman-Monteith模型,蒸散发、土壤蒸发、植被蒸腾,植被总初级生产力

植被总初级生产力(GPP)是指植物通过光合作用吸收的碳&#xff0c;是陆地生物圈和大气之间最大的碳通量&#xff0c;GPP的准确量化对于理解气候变化中生态系统功能、农业生产和碳循环的动态以及对气候的反馈具有重要意义 蒸散发&#xff08;Evapotranspiration&#xff0c;ET&a…

html iframe 框架有哪些优缺点?

目录 前言&#xff1a; 用法&#xff1a; 理解&#xff1a; 优点&#xff1a; 嵌套外部内容&#xff1a; 独立性&#xff1a; 分离安全性&#xff1a; 跨平台兼容性&#xff1a; 方便维护&#xff1a; 缺点&#xff1a; 性能开销&#xff1a; 用户体验问题&#xf…

线性代数-Python-02:矩阵的基本运算 - 手写Matrix及numpy中的用法

文章目录 一、代码仓库二、矩阵的基本运算2.1 矩阵的加法2.2 矩阵的数量乘法2.3 矩阵和向量的乘法2.4 矩阵和矩阵的乘法2.5 矩阵的转置 三、手写Matrix代码Matrix.pymain_matrix.pymain_numpy_matrix.py 一、代码仓库 https://github.com/Chufeng-Jiang/Python-Linear-Algebra-…

驱动开发3 ioctl函数的使用+3个实例(不传递第三个参数、第三个参数为整型、第三个参数为地址)

开发板&#xff1a;stm32mp157aaa&#xff08;Cortex-A7*2 Cortex-M4*1&#xff09;开发环境&#xff1a;vscode、串口工具、ubuntu 18.04 vscode编译过程&#xff1a; 1 引入ioctl函数的意义 linux操作系统中有意将数据的读写和读写功能的选择分别交给不同的函数去完成。就让…

【AI视野·今日Robot 机器人论文速览 第五十七期】Wed, 18 Oct 2023

AI视野今日CS.Robotics 机器人学论文速览 Wed, 18 Oct 2023 Totally 17 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Robotics Papers Underwater and Surface Aquatic Locomotion of Soft Biomimetic Robot Based on Bending Rolled Dielectric Elastomer Actua…

人工智能(6):机器学习基础环境安装与使用

1 库的安装 整个机器学习基础阶段会用到Matplotlib、Numpy、Pandas等库&#xff0c;为了统一版本号在环境中使用&#xff0c;将所有的库及其版本放到了文件requirements.txt当中&#xff0c;然后统一安装 新建一个用于人工智能环境的虚拟环境 mkvirtualenv ai matplotlib3.8…

django 商品及购物车逻辑实现

基于类视图模式实现商品分类菜单接口开发 创建菜单子应用 python manage.py startapp menu测试 apps/menu/views from django.http import HttpResponse from django.views import Viewclass GoodsMainMenu(View):def get(self,request):print("get请求")return …

Java实现连接SQL Server解决方案及代码

下面展示了连接SQL Server数据库的整个流程&#xff1a; 加载数据库驱动建立数据库连接执行SQL语句处理结果关闭连接 在连接之前&#xff0c;前提是确保数据库成功的下载&#xff0c;创建&#xff0c;配置好账号密码。 运行成功的代码&#xff1a; import java.sql.*;publi…

TOGAF(企业架构)

TOGAF 核心概念&#xff08;官方原版&#xff09; 什么是TOGAF&#xff1f; TOGAF?是一种经验证的企业架构方法和框架&#xff0c;被世界领先的组织用于提高业务效率。它是一个企业架构标准&#xff0c;确保企业架构专业人员之间的标准、方法和通信一致&#xff0c;以便我们…

【OpenCV实现图像的算数运算,性能测试和优化,改变颜色空间】

文章目录 OpenCV功能概要图像的算数运算性能测试和优化改变颜色空间对象追踪 OpenCV功能概要 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉和机器学习库&#xff0c;提供了丰富的图像处理和计算机视觉算法。它支持多种编程语言&…

【计算机网络】HTTP协议

文章目录 1. HTTP介绍认识URL 2. HTTP消息结构请求request响应response 3. HTTP请求方法4. HTTP报头5. HTTP响应状态码6. Cookie和Session 1. HTTP介绍 HTTP&#xff08;hypertext transfer protocol&#xff09;是一种常用的应用层协议&#xff0c;用于在计算机之间传输超文本…

Linux常用命令——cksum命令

在线Linux命令查询工具 cksum 检查文件的CRC是否正确 补充说明 cksum命令是检查文件的CRC是否正确&#xff0c;确保文件从一个系统传输到另一个系统的过程中不被损坏。这种方法要求校验和在源系统中被计算出来&#xff0c;在目的系统中又被计算一次&#xff0c;两个数字进行…