Iterator迭代器

news2025/1/12 3:55:18

一、基本概念

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])

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

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

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

相关文章

基于Pytorch的驾驶员分心行为实时检测

本文使用深度学习和Pytorch(PyTorch 2.0.1\Torchvision 0.15.2)实时检测驾驶员的分心行为,并附录完整代码。 检测分心驾驶是现代汽车中最重要的功能之一。无论是自动驾驶汽车还是其它高端汽车,都配备了驾驶员监控系统,以持续跟踪驾驶员的行为。这对确保驾驶员保持目光在道路…

Unity的碰撞检测(二)

温馨提示&#xff1a;本文基于前一篇“Unity的碰撞检测(一)”继续探讨Collider输出&#xff0c;阅读本文则默认已阅读前文。 &#xff08;一&#xff09;测试说明 对于Collider输出&#xff0c;我们首先应该保证两个游戏对象具备的是碰撞器而非触发器&#xff0c;所以碰撞器的…

LSTM算法精解(附案例代码)

概念 LSTM&#xff08;Long Short-Term Memory&#xff09;是一种循环神经网络&#xff08;RNN&#xff09;的变种&#xff0c;用于处理序列数据&#xff0c;特别是在需要长期依赖关系的情况下。LSTM旨在解决传统RNN存在的梯度消失和梯度爆炸问题&#xff0c;这些问题使得RNN难…

18 Transformer 的动态流程

博客配套视频链接: https://space.bilibili.com/383551518?spm_id_from333.1007.0.0 b 站直接看 配套 github 链接&#xff1a;https://github.com/nickchen121/Pre-training-language-model 配套博客链接&#xff1a;https://www.cnblogs.com/nickchen121/p/15105048.html 机…

【BI看板】superset api接口分析

superset 的图表功能已经非常强大了&#xff0c;但是要满足个性化需求&#xff0c;定制是比不可少的了。。。来吧&#xff0c;我们一起看看他的API。 自带api文档 URL 127.0.0.1:5000/swagger/v1 截图 是不是很熟悉&#xff0c;没错就是swagger了。 图表接口地址 127.0.0.1:…

2698 求一个整数的惩罚数 (子集和,DFS)

class Solution { public:bool dfs(int target, string s, int index, int sum) {// 只有整个字符串都被分割&#xff0c;求和&#xff0c;和看结果是不是等于targetif(index s.size()) {return sum target;}int num 0; // 在现在的子集中去依次加入余下的元素// 1 2 9 6// …

vue3 code format bug

vue code format bug vue客户端代码格式化缺陷&#xff0c;为了方便阅读和维护&#xff0c;对代码格式化发现这个缺陷 vue.global.min.3.2.26.js var Vuefunction(r){"use strict";function e(e,t){const nObject.create(null);var re.split(",");for(le…

VLAN实现二层流量隔离(mux-vlan)应用基础配置

MUX VLAN能够提供VLAN内的二层流量隔离机制。 MUX VLAN的类型如下所示 主VLAN: 加入主VLAN的接口可以和MUX VLAN内的所有接口进行通信 从VLAN: (1)隔离型从VLAN: 同一VLAN内接口之间不能互相通信&#xff0c;可以与主VLAN接口通信&#xff0c;不同从VLAN之间不能互相通信。 …

Xcode iOS app启用文件共享

在info.plist中添加如下两个配置 Supports opening documents in place Application supports iTunes file sharing 结果都为YES&#xff0c;如下图所示&#xff1a; 然后&#xff0c;iOS设备查看&#xff0c;文件->我的iPhone列表中有一个和你工程名相同的文件夹出现&…

MySQL——MySQL常见的面试知识

1、事务四大特性 原子性&#xff1a; 根据定义&#xff0c;原子性是指一个事务是一个不可分割的工作单位&#xff0c;其中的操作要么都做&#xff0c;要么都不做。即要么转账成功&#xff0c;要么转账失败&#xff0c;是不存在中间的状态&#xff01;MySQL的InnoDB引擎是靠 un…

Mysql数据库 4.SQL语言 DQL数据操纵语言 查询

DQL数据查询语言 从数据表中提取满足特定条件的记录 1.单表查询 2.多表查询 查询基础语法 select 关键字后指定要查询到的记录的哪些列 语法&#xff1a;select 列名&#xff08;字段名&#xff09;/某几列/全部列 from 表名 [具体条件]&#xff1b; select colnumName…

UI设计公司成长日记2:修身及持之以恒不断学习是要务

作者&#xff1a;蓝蓝设计 要做一个好的UI设计公司,不仅要在能力上设计能力一直&#xff08;十几年几十年&#xff09;保持优秀稳定的保持输出&#xff0c;以及心态的平和宽广。创始人对做公司要有信心&#xff0c;合伙人之间要同甘共苦&#xff0c;遵守规则&#xff0c;做好表…

text-indent 的特殊性

目录 前言 1. text-indent 的基本用法 代码示例 理解 2. text-indent 的特殊性质 2.1 负值 代码示例 理解 2.2 与其他文本属性的交互 代码示例 理解 2.3 在不同元素上的表现 代码示例 理解 3. 如何正确使用 text-indent 前言 text-indent 是 CSS 中一个用来控制…

1401 位置编码公式详细理解补充

博客配套视频链接: https://space.bilibili.com/383551518?spm_id_from=333.1007.0.0 b 站直接看 配套 github 链接:https://github.com/nickchen121/Pre-training-language-model 配套博客链接:https://www.cnblogs.com/nickchen121/p/15105048.html Self-Attention:对于每…

day01:数据库DDL

一:基础概念 数据库:存储数据的仓库&#xff0c;数据是有组织的进行存储 数据库管理系统:操纵和管理数据库的大型软件 SQL&#xff1a;操作关系型数据库的编程语言&#xff0c;定义了一套操作关系型数据库统一标准 关系图 二:数据模型 关系型数据库:建…

LSM树原理详解

LSM树(Log-Structured-Merge-Tree)的名字往往会给初识者一个错误的印象&#xff0c;事实上&#xff0c;LSM树并不像B树、红黑树一样是一颗严格的树状数据结构&#xff0c;它其实是一种存储结构&#xff0c;目前HBase,LevelDB,RocksDB这些NoSQL存储都是采用的LSM树。 LSM树的核…

基于Java的智能仓库(进销存)管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09; 代码参考数据库参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&am…

USB学习(2):USB端点和传输协议(数据包、事物)详解

接着上一篇文章USB学习(1)&#xff1a;USB基础之接口类型、协议标准、引脚分布、架构、时序和数据格式&#xff0c;继续介绍一下USB的相关知识。 文章目录 1 USB端点(Endpoints)1.1 基本知识1.2 四种端点 2 传输协议2.1 数据包类型2.1.1 令牌数据包(Token packets)2.1.2 数据数…

目标检测应用场景—数据集【NO.16】交通标志检测

写在前面&#xff1a;数据集对应应用场景&#xff0c;不同的应用场景有不同的检测难点以及对应改进方法&#xff0c;本系列整理汇总领域内的数据集&#xff0c;方便大家下载数据集&#xff0c;若无法下载可关注后私信领取。关注免费领取整理好的数据集资料&#xff01;今天分享…

基于Java的智能停车场管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09; 代码参考数据库参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&am…